Баш, попередження без аргументів та рішення справи


110

Я вчу баш.

Я хотів би зробити простий сценарій, який, якщо не наводиться аргументів, показує якесь повідомлення. І коли я даю число в якості аргументу, s залежно від значення, воно робить те чи інше.

Я також хотів би знати пропозиції щодо кращих онлайн-посібників для початківців в баші

Дякую

Відповіді:


176
if [[ $# -eq 0 ]] ; then
    echo 'some message'
    exit 0
fi

case "$1" in
    1) echo 'you gave 1' ;;
    *) echo 'you gave something else' ;;
esac

Advanced Bash-Scripting Guide досить добре. Незважаючи на свою назву, він все-таки ставиться до основ.


RE: "вихід 0". Я не знаю, чи був вихід із сценарію тим, що він мав на увазі. Але так, це відмінне керівництво.
Трампас Кірк

Я інтерпретував "і" як "інакше", припускаючи, що повідомлення буде деяким довідковим текстом. Але я впевнений , що Вернер здатний з'ясувати , що робить цей рядок , і чи хоче він це :)
Томас

дякую, звичайно! і останнє, як я можу вимкнути повідомлення про помилки ib у скрипті, щоб вони не відображалися до оболонки?
Відкрийте дорогу

Ви маєте на увазі помилки, що виникають у певній програмі, яку ви телефонуєте? Ви можете поставити > /dev/nullта / або 2> /dev/nullпісля цього відіслати його стандартний вихід та / або стандартні потоки помилок у небуття.
Томас

4
Якщо ви вважаєте, що відсутній аргумент є поганим (наприклад, сценарій не може успішно виконати), поверніть щось інше, ніж 0 ( exit 1). Існують додаткові умови щодо кодів повернення / виходу, які ви можете швидко знайти в Інтернеті, але важливим моментом є те, що він не повинен бути 0, що свідчить про успіх.
Фелікс

25

Якщо зацікавлений лише в заставі, якщо конкретний аргумент відсутній, Параметр Заміна чудово:

#!/bin/bash
# usage-message.sh

: ${1?"Usage: $0 ARGUMENT"}
#  Script exits here if command-line parameter absent,
#+ with following error message.
#    usage-message.sh: 1: Usage: usage-message.sh ARGUMENT

11

Приклад

 if [ -z "$*" ]; then echo "No args"; fi

Результат

No args

Деталі

-z - одинарний оператор, для якого довжина рядка дорівнює нулю. $*це всі аргументи. Цитати є для безпеки та укладають декілька аргументів, якщо вони є.

Використовуйте man bashта шукайте ( / клавішу) "unary" для таких операторів.


7
(Незначна) проблема в тому, що він не розрізняє передачу аргументів і передачу порожнього рядка як аргументу. Це може бути важливо в деяких контекстах. Використовуючи [$ # -eq 0] можна правильно обробити обидва випадки.
Іделік

1
Ах, тонкощі (ба) ш програмування ... Ось чому я його ненавиджу.
Томас

1
думати , -zяк mizzing
Рей Фосс

4

Старий, але у мене є підстави переробити відповідь зараз завдяки певній плутанині:

if [[ $1 == "" ]] #Where "$1" is the positional argument you want to validate 

 then
 echo "something"
 exit 0

fi

Це повториться "Щось", якщо позиційного аргументу немає $ 1. Однак це не підтверджує, що $ 1 містить конкретну інформацію.


$#явно ціле число числа аргументів; це буде або "0", і ви будете лунати "чимось", хоча аргументів немає, або це буде якесь позитивне число, і ви будете правильно повторювати "щось". Але сама перевірка ніколи нічого не зробить, незалежно від використовуваного вводу або відсутності входу - він завжди повідомляє, що $#містить значення. Тож це абсолютно неправильно і ніколи не буде працювати, як заявлено.
eschwartz

Ви в цьому повністю позитивні? У мене є кілька сценаріїв, які працюють за призначенням, використовуючи саме цей формат. Прочитавши вашу відповідь, я навіть повторився як на матч, так і на його відсутність. $ # не буде містити значення, якщо його не вказано, якщо немає жодного позиційного аргументу, який би відповідав тому, що коли-небудь є у вашому сценарії. Немає сенсу, чому bash прийме значення в позиційному аргументі, якого немає.
Райан Сміт

Спробуйте echo $#як вміст сценарію /tmp/test.sh, а потім запустіть його під / bin / bash, а також / bin / sh (або / bin / dash та будь-які інші реалізації оболонок, які у вас є. /tmp/test.shЗвучить "0" до з /bin/dash /tmp/test.shіншого боку, /tmp/test.sh fooбуде лунати "1", і /tmp/test.sh first second
лунатиме

Відповідно man bash, у розділі "Спеціальні параметри" "Оболонка спеціально обробляє декілька параметрів. Ці параметри можуть бути лише посиланнями; присвоєння їм заборонено." Та "# Розширює кількість позиційних параметрів у десятковій частині. Це також доручено POSIX, як описано в pubs.opengroup.org/onlinepubs/9699919799/utilities/…
eschwartz

Вибачте, схоже, сталася помилка! Я мав на увазі # як власник місця для конкретного позиційного аргументу (тобто, $ 2, якщо ви мали на увазі другий аргумент), а не буквального $ #. Переглянувши вищесказане, ви абсолютно правильні, буквальна $ # завжди вирішить кількість аргументів. Вибачення за плутанину.
Райан Сміт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.