Я означаю выполнять 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
содержите в среде вызова, вместо того, чтобы оценить внутри.
То, в чем я нуждаюсь, является на самом деле комбинацией вещей работать:
Оцените правильно files=*
в рабочей среде и каталоге (это на самом деле был бы другой шаблон, но это не важно).
Циклично выполнитесь правильно ${files}
, с for file in ${files}
(вместо for file in {0..2}
).
Используйте строковую замену с do mv $file ${file/-0003/-0002}
(вместо do echo ${file}
). Это, объединенное с потребностью в вызове от C++ с system
, то, что вынуждает меня предварительно ожидать команду с bash
, как с system("bash -c ...");
. Если я не предварительно ожидаю его, оболочка по умолчанию dash
используется, который не поддерживает строковую замену, давая мне ошибку sh: 1: Bad substitution
.
Этот вопрос конкретен.
Кроме того, любая другая альтернатива, которая позволяет мне делать системный вызов из C++ и выполнять: 1) подстановочное использование файла, 2) строковую замену, 3) надлежащее цикличное выполнение, был бы в порядке.
Используйте массив и соответствующее заключение в кавычки. Например, данный:
$ 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
С двойными кавычками переменные будут расширены в оболочке вызова. Используйте одинарные кавычки:
$ 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);
}