Принять переменное количество аргументов и выполнить их

Мне нужна функция 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 может быть изменен. Есть ли способ добиться желаемого поведения?

1
задан 3 July 2019 в 09:03

1 ответ

Можно отсортировать, делают это, но, как 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'
1
ответ дан 7 December 2019 в 15:00

Другие вопросы по тегам:

Похожие вопросы: