Обработка всех аргументов, кроме первого (в скрипте bash)

254

У меня есть простой script, где первый аргумент зарезервирован для имени файла, а все остальные необязательные аргументы должны быть переданы другим частям script.

Используя Google, я нашел эту вики, но он предоставил буквальный пример:

echo "${@: -1}"

Я не могу заставить ничего работать, например:

echo "${@:2}"

или

echo "${@:2,1}"

Я получаю "плохую замену" с терминала.

В чем проблема, и как я могу обработать все, кроме первого аргумента, переданного в bash script?

  • 12
    Чтобы призвать кого-то еще запутать, был предоставлен неправильный шебанг, в результате чего "{@:2}" не работал, поэтому правильный ответ совпадает с приведенным выше.
  • 2
    Вы только что использовали оболочку по умолчанию, которая является чертой в Ubuntu и многих других Linux. В тире «$ {@: -1}» интерпретируется как: {параметр: -word} - Использовать значения по умолчанию и использовать слово, если параметр не определен или имеет значение NULL. Так что в тире "$ {@: -1}" результаты точно такие же, как и "$ @". Чтобы использовать bash, просто используйте следующую первую строку в файле сценария: #! / Bin / bash
Теги:

3 ответа

331
Лучший ответ

Используйте это:

echo "${@:2}"

Следующий синтаксис:

echo "${*:2}"

будет работать, но не рекомендуется, потому что @Gordon уже объяснил, что с помощью * он запускает все аргументы вместе как один аргумент с пробелами, а @ сохраняет разрывы между ними (даже если некоторые из самих аргументов содержат пробелы). Это не имеет значения с echo, но это важно для многих других команд.

  • 4
    Я только что понял, что мой шебанг был плохим: #!/usr/bin/env sh Вот почему у меня были проблемы. Вы пример работает нормально, так же, как указано выше, после того, как я удалил этот shebang
  • 98
    Вместо этого используйте "${@:2}" - использование * запускает все аргументы вместе как один аргумент с пробелами, в то время как @ сохраняет разрывы между ними (даже если некоторые из аргументов сами содержат пробелы). С echo разница не заметна, но имеет значение для многих других вещей.
Показать ещё 6 комментариев
117

Если вы хотите решение, которое также работает в /bin/sh, попробуйте

first_arg="$1"
shift
echo First argument: "$first_arg"
echo Remaining arguments: "$@"

shift [n] сдвигает позиционные параметры n раз. A shift устанавливает значение $1 на значение $2, значение $2 на значение $3 и т.д., Уменьшая значение $# на единицу.

  • 23
    +1: Вам, вероятно, следует сохранить $ 1 в переменную, прежде чем сдвинуть ее.
  • 3
    Удивительно, но foo=shift не делает то, что я ожидал.
Показать ещё 2 комментария
2

http://wiki.bash-hackers.org/scripting/posparams

В нем объясняется использование shift (если вы хотите отбросить первые N параметров), а затем реализовать массовое использование (найдите заголовок с этим заголовком).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню