Выполнение команды в ударе, переданном как строка, с надлежащей подстановочной операцией файла

Я означаю выполнять a bash команда, переданная явно как строка к bash, который может обработать правильно подстановочный знак файла и переменные операции расширения.

Я попробовал демонстрационную команду (см. ниже для того, в чем я на самом деле нуждаюсь, который более "требователен"):

$ bash -c "files=* ; echo ${files} ; for file in {0..2} ; do echo ${file} ; done"

и я получаю 4 пустых строки (один от echo ${files} и три от for file in {0..2} ...). На самом деле это отзовется эхом что переменные files и file содержите в среде вызова, вместо того, чтобы оценить внутри.

То, в чем я нуждаюсь, является на самом деле комбинацией вещей работать:

  1. Оцените правильно files=* в рабочей среде и каталоге (это на самом деле был бы другой шаблон, но это не важно).

  2. Циклично выполнитесь правильно ${files}, с for file in ${files} (вместо for file in {0..2}).

  3. Используйте строковую замену с do mv $file ${file/-0003/-0002} (вместо do echo ${file}). Это, объединенное с потребностью в вызове от C++ с system, то, что вынуждает меня предварительно ожидать команду с bash, как с system("bash -c ...");. Если я не предварительно ожидаю его, оболочка по умолчанию dash используется, который не поддерживает строковую замену, давая мне ошибку sh: 1: Bad substitution.

Этот вопрос конкретен.

Кроме того, любая другая альтернатива, которая позволяет мне делать системный вызов из C++ и выполнять: 1) подстановочное использование файла, 2) строковую замену, 3) надлежащее цикличное выполнение, был бы в порядке.

0
задан 8 May 2017 в 07:26

2 ответа

Используйте массив и соответствующее заключение в кавычки. Например, данный:

$ ls
file1  file2  file4  file5  file6

затем

$ bash -c 'files=(*) ; echo "${files[@]}" ; for file in "${files[@]}" ; do echo "${file/2/3}" ; done'
file1 file2 file4 file5 file6
file1
file3
file4
file5
file6
2
ответ дан 3 November 2019 в 07:05

С двойными кавычками переменные будут расширены в оболочке вызова. Используйте одинарные кавычки:

$ cd /; bash -c 'files=* ; echo ${files} ; for file in {0..2} ; do echo ${file} ; done'
bin boot dev etc home lib lib64 lost+found mnt opt proc root run sbin srv sys tmp usr var
0
1
2

необходимо на самом деле использовать массивы, но:

Вы должны на самом деле fork и exec , если Вы хотите назвать определенную команду с определенными аргументами:

#include <unistd.h>
#include <cstdio>
#include <sys/types.h>
#include <sys/wait.h>

int main()
{
    pid_t child = fork();
    if (child == -1) // fork failed
        std::perror("fork");
    else if (child == 0) // child
        execl("/bin/bash", "bash", "-c", "files=* ; echo ${files} ; for file in {0..2} ; do echo ${file} ; done", NULL);
    else // parent
        wait(NULL);
}
1
ответ дан 3 November 2019 в 07:05

Другие вопросы по тегам:

Похожие вопросы: