Я хочу выполнить команду 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
Используйте массив и соответствующее цитирование. Например, данный:
$ 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
Используйте массив и соответствующее цитирование. Например, данный:
$ 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);
}
С двойными кавычками переменные будут расширены в вызывающей оболочке. Используйте одиночные кавычки:
$ 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);
}
С двойными кавычками переменные будут расширены в вызывающей оболочке. Используйте одиночные кавычки:
$ 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);
}