Как заставить удар прервать выполнение сценария на синтаксической ошибке?

Для конкатенации файлов, Вы используете

cat file1 file2 file3 ...

Для получения списка заключенных в кавычки имен файлов, отсортированных по времени, новейшему первый, Вы используете

ls -t

Соединение всего этого,

cat $(ls -t) > outputfile

Вы могли бы хотеть дать некоторые аргументы ls (например, *.html).

Но если у Вас будут имена файлов с пробелами в них, то это не будет работать. My file.html как будет предполагаться, будет двумя именами файлов: My и file.html. Можно сделать ls заключите имена файлов в кавычки и затем используйте xargs, кто понимает заключение в кавычки, для передачи аргументов cat.

ls -tQ | xargs cat

Что касается Вашего второго вопроса, отфильтровывая части файлов не является трудным, но он зависит от того, что точно Вы хотите разделить. Каковы “избыточные заголовки”?

15
13.04.2017, 15:37
4 ответа

Обертывание целого в функцию, кажется, добивается цели:

#!/bin/bash -e

main () {
readonly a=(1 2)
    # A syntax error is here:
    if (( "${a[#]}" == 2 )); then
        echo ok
    else
        echo not ok
    fi
    echo status $?
    echo 'Bad: has not aborted execution on syntax error!'
}

main "$@"

Результат:

$ ./sh-on-syntax-err 
$ ./sh-on-syntax-err line 6: #: syntax error: operand expected (error token is "#")
$ 

Хотя у меня нет подсказки, почему - возможно, кто-то еще может объяснить?

9
27.01.2020, 19:50
  • 1
    Теперь Ваше функциональное определение проанализировано и оценено, и оно перестало работать. –  tripleee 08.07.2013, 20:00
  • 2
    Хорошее решение! BTW, это не прерывает целую программу в этом случае, также. Я добавил echo 'Bad2: has not aborted the execution after bad main!' поскольку последнее к Вашему примеру и вывод: $ LC_ALL=C./sh-on-syntax-err./sh-on-syntax-err: строка 6: #: синтаксическая ошибка: операнд ожидал (ошибочный маркер является "#"), Bad2: не прервал выполнение после плохо основной! $ –  imz -- Ivan Zakharyaschev 08.07.2013, 20:32
  • 3
    , Но мы не должны добавлять строку просто затем, мы должны поместить все в функции. –  imz -- Ivan Zakharyaschev 08.07.2013, 20:33
  • 4
    @tripleee Да, это похоже на парсинг функциональных сбоев, таким образом, это не завершено, но целая программа не прерывается на самом деле в этом случае (таким образом, это не эффект выхода на ошибке, вероятно). –  imz -- Ivan Zakharyaschev 08.07.2013, 20:34

Вы, вероятно, вводят в заблуждение о подлинном значении set -e. Тщательное чтение вывода help set шоу:

-e  Exit immediately if a command exits with a non-zero status.

Так -e о статусе выхода команд, являющихся ненулевым, не о синтаксических ошибках в Вашем сценарии.

В целом это считают плохой практикой для использования set -e, потому что все ошибки (т.е. все ненулевые возвраты из команд) должны быть энергично обработаны сценарием (думайте устойчивый сценарий, не те, которые взбесились после ввода имени файла с пространством, или это запускается с дефиса).

В зависимости от типа синтаксической ошибки сценарий даже не мог бы быть выполнен вообще. Я не достаточно хорошо осведомлен в ударе для сообщения точно, что класс синтаксических ошибок (если только они могут быть классифицированы) мог бы привести к непосредственному прерыванию сценария или нет. Возможно, некоторые гуру Bash присоединятся и разъяснят все.

Я только надеюсь, что разъяснился set -e оператор!

О Вашем желании:

Я ожидал такое безопасное поведение от разумного языка программирования..., возможно, это, как должны сообщать, как ошибка/желание колотит разработчиков

Ответ определенно нет! как, что Вы наблюдали (set -e никакой ответ, как Вы ожидаете) на самом деле очень хорошо документируется.

6
27.01.2020, 19:50
  • 1
    я имел в виду отсутствие такой функции, является проблемой. Я не хотел фокусироваться на set -e - это просто немного близко к моим целям, вот почему это упоминается и используется здесь. Мой вопрос не о set -e, это о небезопасности удара, если это не может быть сделано прерваться на sytax ошибках. Я ищу способ заставить его всегда прерваться на синтаксических ошибках. –  imz -- Ivan Zakharyaschev 08.07.2013, 23:30

Вы могли осуществить саму проверку сценария путем помещения чего-то как

bash -n "$0"

около верхней части сценария - после set -e но перед любой значительной частью кода.

Я должен сказать, что это не чувствует себя очень устойчивым, но если это работает на Вас, возможно, это приемлемо.

4
27.01.2020, 19:50
  • 1
    Превосходный! Или, без set -e: bash -n "$0" || exit –  Daniel S 27.08.2015, 12:56

Во-первых, (( )) в ударе используется в качестве арифметических вычислений, для не использования в, если... используют [] для этого.

Во-вторых, ${a[#]} является странным, и то, почему предоставление ошибок... # не имеет никакого значения массива

Я не знаю то, что Вы хотите сделать с этим, но я предполагаю, что Вы хотите знать количество полей, таким образом, Вы хотите ${#a[*]} вместо этого

Наконец, при сравнении целых чисел, -eq рекомендуется == (используемый для строк). == будет также работать, но -eq рекомендуется.

таким образом, Вы хотите:

if [ ${#a[*]} -eq 2 ]; then 
0
27.01.2020, 19:50
  • 1
    Это не верно. Распространено использовать (( ключевое слово с if ключевое слово. Например, if (( 5 * $b > 53 )). Если Вы не стремитесь к мобильности с более старыми оболочками, [[ обычно предпочтителен законченный [. –   08.07.2013, 22:11
  • 2
    Да, я соглашаюсь с @Evan- [[ и (( были специально разработаны, поскольку легкий вес тестирует, чтобы использоваться с "если" и т.д. - в отличие от этого, [, они никогда не порождают подпроцесс для оценки условия. –  imz -- Ivan Zakharyaschev 08.07.2013, 23:33
  • 3
    [ встроенный удар. Более старые оболочки ожидают, что это будет своей собственной программой все же. –   09.07.2013, 00:24

Теги

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