Попробуйте использовать перенаправление стандартного вывода. Например
./program-name > myfile.log 2>&1
Другой метод
stdbuf -oL./program-name > myfile.log 2>&1 &
Я на iPad, не могу ссылаться на источники перенаправления atm.
Вам также не нужна строка -name a -prune -o name b c -prune...
, поскольку на самом деле команда, которую вы запускаете, является не одной строкой, а несколькими строками. Просто когда вы пишете foo bar "a b"
, оболочка интерпретирует кавычки и разбивает командную строку на пробелы без кавычек, давая вам три строки foo
, bar
и a b
. Точно так же вы хотите в конечном итоге перейти к find
— это аргументы -o
, -name
, a b
, -prune
и т. д. Если у вас есть строка -o -name a b -prune
, трудно сделать так, чтобы строка разделяется на другие пробелы, но не разделяется между a
и b
.
Во-первых, вам нужно каким-то образом прочитать список имен, разделенных новой строкой -, не разрывая отдельные строки. Поскольку вы упомянули Bash, для этого есть команда mapfile
(readarray
). Давайте пока предположим, что у вас есть этот список имен в другом файле. Затем
readarray -t names < listfile
заполнит массив names
содержимым файла, по одной записи в строке.
Обратите внимание, что в вашем вопросе строка в myList
также содержит обратную косую черту и пробелы перед вторым и третьим каталогами, которые вы, вероятно, захотите очистить, если будете хранить список таким образом. Или вы можете просто сохранить список как массив напрямую, как в ответе @James S. .
Затем вторая проблема заключается в построении списка аргументов для find
. Там вам также нужен массив, чтобы сохранить аргументы нетронутыми и отдельными. Итак,
args=()
for n in "${names[@]}"; do
args+=(-name "$n" -prune -o)
done
заполнит массив args
аргументами. Затем вы использовали бы его как
find... "${args[@]}"
Кроме того, вам не нужно повторять -prune
, вы можете заключить все это в круглые скобки и просто иметь -prune
один раз снаружи, например. в командной строке,вы бы использовали ... "(" -name this -o -name that ")" -prune...
, и вы могли бы заполнить массив примерно так
args=("(")
for n in "${names[@]}"; do
args+=(-name "$n" -o)
done
unset "args[${#args[@]} - 1]" # remove the last -o
args+=( ")" -prune )
См.:
Я думаю, вы могли бы использовать специальную переменную IFS
#!/bin/bash
OFS=$IFS
IFS=$'\n'
myList="a \\
b c \\
d"
dirList=
stringArray=($myList)
for i in "${stringArray[@]}" ; do
dirList="$dirList -name $i -prune -o"
echo "$dirList"
echo " "
done
IFS=$OFS
Это заданный выход:
-name a \ -prune -o
-name a \ -prune -o -name b c \ -prune -o
-name a \ -prune -o -name b c \ -prune -o -name d -prune -o