Как сохранить команду в переменной в Linux?
Я хотел бы сохранить команду для использования в более поздний период в переменной (не вывод команды, а сама команда)
у меня есть простой скрипт следующим образом:
command="ls";
echo "Command: $command"; #Output is: Command: ls
b=`$command`;
echo $b; #Output is: public_html REV test... (command worked successfully)
однако, когда я пытаюсь что-то немного сложнее, это не удается. Например, если я сделаю
command="ls | grep -c '^'";
выход:
Command: ls | grep -c '^'
ls: cannot access |: No such file or directory
ls: cannot access grep: No such file or directory
ls: cannot access '^': No such file or directory
любая идея, как я мог бы хранить такую команду (с трубами/несколькими командами) в переменной для последующего использования?
4 ответа:
сделать не использовать
eval! Он имеет большой риск введения выполнения произвольного кода.BashFAQ-50 - Я пытаюсь поместить команду в переменную, но сложные случаи всегда терпят неудачу.
поместите его в массив и разверните все слова с двойными кавычками
"${arr[@]}"до не пустьIFSразделить слова из-за Разбиение.cmdArgs=() cmdArgs=('date' '+%H:%M:%S')и посмотреть содержимое массива внутри. Элемент
declare -pпозволяет увидеть содержимое массива внутри с каждым параметром команды в отдельных индексах. Если один из таких аргументов содержит пробелы, цитирование внутри при добавлении в массив предотвратит его разделение из-за разделения слов.declare -p cmdArgs declare -a cmdArgs='([0]="date" [1]="+%H:%M:%S")'и выполнить команды как
"${cmdArgs[@]}" 23:15:18(или) вообще использовать
bashфункция для выполнения команды,cmd() { date '+%H:%M:%S' }и вызовите функцию как только
cmdPOSIX
shне имеет массивов, поэтому самое близкое, что вы можете сделать, это создать список элементов в позиционных параметрах. Вот это POSIXshспособ запуска программы mail# POSIX sh # Usage: sendto subject address [address ...] sendto() { subject= shift first=1 for addr; do if [ "$first" = 1 ]; then set --; first=0; fi set -- "$@" --recipient="$addr" done if [ "$first" = 1 ]; then echo "usage: sendto subject address [address ...]" return 1 fi MailTool --subject="$subject" "$@" }
var=$(echo "asdf") echo $var # => asdfиспользуя этот метод, команда немедленно вычисляется и ее возвращаемое значение сохраняется.
stored_date=$(date) echo $stored_date # => Thu Jan 15 10:57:16 EST 2015 # (wait a few seconds) echo $stored_date # => Thu Jan 15 10:57:16 EST 2015то же самое с backtick
stored_date=`date` echo $stored_date # => Thu Jan 15 11:02:19 EST 2015 # (wait a few seconds) echo $stored_date # => Thu Jan 15 11:02:19 EST 2015используя eval в
$(...)не будет оцениваться позжеstored_date=$(eval "date") echo $stored_date # => Thu Jan 15 11:05:30 EST 2015 # (wait a few seconds) echo $stored_date # => Thu Jan 15 11:05:30 EST 2015используя eval, он оценивается, когда
evalиспользуетсяstored_date="date" # < storing the command itself echo $(eval $stored_date) # => Thu Jan 15 11:07:05 EST 2015 # (wait a few seconds) echo $(eval $stored_date) # => Thu Jan 15 11:07:16 EST 2015 # ^^ Time changedв приведенном выше примере, Если вам нужно выполнить команду с аргументами, положить их в строку, хранение
stored_date="date -u" # ...для скриптов bash это редко актуально, но последнее замечание. Будьте осторожны с
eval. Eval только строки, которыми вы управляете, никогда не строки, поступающие от ненадежного пользователя или построенные из ненадежного пользовательского ввода.