Мне нужна функция bash, чтобы принимать переменное число аргументов. Эти аргументы являются другими командами, такими как ls /root
, echo HI
, git clone http:// ....
, rm
и т. Д. Функция выполняет команды последовательно
Функция должна принимать аргументы как:
myfun <arbitrary set of commands>
Обратите внимание, что каждая команда может иметь произвольный набор параметров для себя.
myfun echo H ls /root git clone http://.... /home/myh/git/x1
myfun должен выполняться следующим образом
echo H
ls /root
git clone http://.... /home/myh/git/x1
Способ передачи аргументов в myfun
может быть изменен. Есть ли способ добиться желаемого поведения?
Можно отсортировать, делают это, но, как Michal Przybylowicz предполагает, Вы не были должны. Если Вы знаете, что хотите сделать это, Вы могли бы перескочить; иначе рассмотрите эти альтернативы.
;
.&
. это выполнит их всех в фоновом режиме кроме последнего. Если Вы хотите, чтобы последний работал в фоновом режиме, поместите a &
после него, также.&&
вместо ;
.{
}
. Вам нужно пространство после открытия {
. Закрытие }
должен или появиться на новой строке или иметь a ;
перед ним. Примените перенаправления после закрытия }
, на той же строке. Например, { echo H; ls /root; } >out.txt
.help history
и help fc
. Если Вы хотите сразу показать команды, которые будут выполнены, а также выполняют их, используют set -x
; посмотрите help set
для деталей.Причина, которую Вы не должны обычно писать функции, которая выполняет каждый из ее аргументов как полная команда, состоит в том, что это было бы громоздким и подверженным ошибкам для использования такой функции, потому что необходимо будет заключить в кавычки каждый аргумент, который состоит из нескольких слов (т.е. это передает один или несколько аргументов команде). Это не могло бы казаться настолько плохим..., пока Вы не понимаете, что некоторым Вашим аргументам, возможно, самостоятельно было нужно заключение в кавычки так или иначе, в этом случае необходимо заключить кавычки в кавычки, также. Это осуществимо, но далеко от идеала.
Как конкретный пример проблемы, рассмотрите команду, Вы предположили, что смогли работать для вызова функции:
myfun echo H ls /root git clone http://.... /home/myh/git/x1
Это не будет работать. Как myfun
предполагаемый знать, где концы команды и следующий начинается?
Если Вы действительно хотите сделать это, один разумный подход должен использовать eval
встроенный (см. help eval
). Вызовите функцию вообще, Вам нравится, это нельзя назвать eval_all
:
eval_all() { for cmd; do eval "$cmd"; done; }
for cmd
имеет тот же эффект как for cmd in "$@"
. Используйте любое имя, которое Вы любите за cmd
переменная; просто не забудьте изменяться $cmd
соответственно. Если Вы не хотите писать в a cmd
переменная используется вне функции:
eval_all() { local cmd; for cmd; do eval "$cmd"; done; }
Однако Вы решили записать эту функцию, если Вы хотели использовать ее для выполнения команд echo H
и ls
, Вы назвали бы его как это:
eval_all 'echo H' ls
Но можно уже сделать это, которое более хорошо:
echo H; ls
Если Вы также хотели, чтобы это выполнило команду touch 'honest $$$$ ideas.txt'
, Вы назвали бы его как это:
eval_all 'echo H' ls 'touch '\''honest $$$$ ideas.txt'\'
Существуют другие способы заключить одинарные кавычки в кавычки. Ни один из них не особенно симпатичен. Ни один не почти так же хорош как:
echo H; ls; touch 'honest $$$$ ideas.txt'