Флаги Bash с опциональным чтением из стандартного ввода - PullRequest
0 голосов
/ 04 апреля 2019

Я знаю, что это, вероятно, глупый вопрос, но он поставил меня в тупик.Я пытаюсь написать сценарий оболочки, который принимает флаги и одну необязательную переменную.Файл.Если файл передан, он читает из файла.Если нет, он читает со стандартного ввода.Я знаю, что подобные вопросы задавались, но я не могу найти ответ на свой конкретный вопрос.

Ниже приведен пример, иллюстрирующий проблему.Для краткости я оставил некоторые части (например, проверку).

Я могу принимать флаги и читать из файла.ИЛИ При желании я могу принять переменную (файл) и прочитать из файла.Если файл не передается, мы читаем из стандартного ввода.По какой-то причине, когда я пытаюсь объединить их (принять флаги, прочитать необязательный файл по умолчанию в stdin), я получаю сообщение об ошибке.

Это работает.

#!/bin/sh
set -eu

while IFS=, read -r f1 
do
  echo $f1
done <"${1:-/dev/stdin}"

Я могу назвать это какэто ... ./test.sh <<< "testing123" или это ... echo "testing123" | ./test.sh или это ... ./test.sh foo.csv.Все возвращают testing123, предполагая, что foo.csv содержит testing123.

Это также работает.

#!/bin/sh
set -eu

while true
do
  case $1 in
    -h|--help)
      echo "-h"
      exit
      ;;
    --)
      shift
      break
      ;;
    -?*)
      echo "unknown"
      ;;
    *)
      break
  esac

  shift
done

while IFS=, read -r f1 
do
  echo $f1
done <"${1}"

Я могу назвать это так ./test.sh foo.csv или ./test.sh -f foo.csv.В первом случае возвращается testing123, а во втором -

unknown
testing123

По какой-то причине это не работает.Я не понимаю, чего мне здесь не хватает?

#!/bin/sh
set -eu

while true
do
  case $1 in
    -h|--help)
      echo "-h"
      exit
      ;;
    --)
      shift
      break
      ;;
    -?*)
      echo "unknown"
      ;;
    *)
      break
  esac

  shift
done

while IFS=, read -r f1 
do
  echo $f1
done <"${1:-/dev/stdin}"

Называется вот так ./test foo.csv возвращается testing123.Вызывается так: ./test -f foo.csv возвращается

unknown
testing123

Вызывается так:

echo "testing123" | ./test.sh

или это

./test.sh <<< "testing123"

возвращается

./test.sh: line 6: $1 unbound variable

1 Ответ

1 голос
/ 04 апреля 2019

Изменение

while true

до

while [ $# -ne 0 ]

Когда у вас заканчиваются аргументы, ваш код продолжает следующую итерацию цикла и пытается проверить $1, которого не существует. Поскольку вы выполнили set -eu, ссылка на неустановленную переменную вызывает ошибку, и сценарий прерывается.

...