Bash set x что это
Перейти к содержимому

Bash set x что это

  • автор:

Команда Bash `set -x`

Команда Bash set используется для многих целей в bash и имеет множество параметров для включения или отключения различных типов функций среды оболочки. Параметр -x — это один из параметров команды set, которая используется для включения функции отладки сценария bash для устранения неполадок. Команду `set -x` можно использовать из терминала или внутри любого скрипта bash. В этом руководстве описаны различные цели использования команды `set -x`.

Включить отладку

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

Функцию отладки можно включить с помощью команды `set -x` в терминале или внутри скрипта bash с помощью команды `set –x`. Использование команды `set -x` было показано в следующей части руководства.
Функцию отладки также можно включить, используя параметр -x во время выполнения файла bash, например следующую команду:

$ bash -x filename.bash

Функцию отладки также можно включить, используя следующую строку в начале скрипта:

Отключить отладку

Требуется отключить функцию отладки скрипта bash после решения проблемы. Команда `set +x` используется для отключения функции отладки.

Различные примеры использования команды `set -x`

На примерах показаны два разных использования параметра `set -x`.

Пример 1: включение и отключение функции отладки

Создайте файл bash с помощью следующего сценария, который будет принимать данные от пользователя до и после использования команд `set -x` и `set +x`. Первое значение имени будет взято и напечатано перед использованием команды `set -x`. Значение последнего имени будет взято и напечатано после использования команды `set -x`. Затем значения имени и фамилии будут напечатаны после использования команды `set +x`.

#Take input and print

read -p «Enter your first name: » firstname

echo «Your first name is $firstname «

#Enable the set -x command

#Take another input and print

read -p «Enter your last name: » lastname

echo «Your last name is $lastname «

#Disable the set x command

#Print the variables

echo «Your fullname is $firstname $lastname «

Вывод:

Следующий вывод будет напечатан после выполнения вышеуказанного скрипта. Согласно выходным данным, каждый оператор сценария был напечатан после выполнения команды `set -x`.

Пример 2: отладка скрипта с помощью команды `set -x`

Создайте файл bash со следующим сценарием, который будет принимать имя файла от пользователя для чтения, включив функцию отладки. Команда `set -x` использовалась в начале скрипта для включения функции отладки. Далее у пользователя будет взято имя файла. Если имя файла не указано пользователем, будет напечатано сообщение. Если имя файла, полученное от пользователя, не существует или не является файлом, будет отображено другое сообщение об ошибке. Если у пользователя берется действительное имя файла, содержимое файла будет напечатано.

#Enable the debugging

#Take the filename from the user

echo -n «Enter a filename:»

#Check whether the filename is empty or not

echo «Filename is missing.»

#Check whether the file exists or not

#Print error message

echo » $fn does not exist.»

#Print the file content

Вывод:

Следующий вывод появится после выполнения вышеуказанного скрипта без указания имени файла. Вывод показывает, что в качестве имени файла было взято пустое значение. Условие `if` для проверки пустого имени файла было возвращено true для пустого ввода. Таким образом, оператор `echo` для печати сообщения об ошибке был напечатан для опции отладки, и было напечатано сообщение об ошибке «Имя файла отсутствует».

Следующий вывод появится после выполнения вышеуказанного скрипта с именем файла. Вывод показывает, что условие `if` для проверки пустого имени файла было возвращено как ложное, и условие `if` для проверки несуществующего файла также было возвращено ложно. Имя входного файла testfile.txt существует в текущем местоположении. Итак, команда `cat` для чтения файла testfile.txt была выполнена, и содержимое файла было напечатано.

Следующий вывод появится после выполнения вышеуказанного скрипта с именем файла. Вывод показывает, что условие `if` для проверки пустого имени файла было возвращено как ложное, а условие `if` для проверки несуществующего файла было возвращено как истина, поскольку file1.txt не существуют в текущем местоположении. Таким образом, команда `cat` для чтения файла не была выполнена, и было напечатано сообщение об ошибке «file1.txt не существует.».

Заключение

Задача отладки — очень важная часть любого языка программирования, позволяющая легко обнаружить ошибку в коде. Задача отладки выполняется по-разному для разных языков программирования. В этом руководстве описано несколько способов включения функции отладки для сценария bash и использование команды set -x для отладки сценария bash.

Безопасные bash-скрипты или set -euxo pipefail

В 2020 году когда есть такие языки как python, ruby и go, использовать bash приходится редко, но иногда без него не обойтись.

Bash не похож на высокоуровневые языки программирования, он не предоставляет привычных гарантий. К примеру, если в python обратиться к неинициализированной переменной, то скрипт тут же завершиться, не выполнив ни одной инструкции. В bash это не так, любая переменная, к которой вы обратились, но не инициализировали, будет заменена на пустую строку. Только представьте сколько можно наворотить дел, если подобная переменная была в параметрах у команды rm -rf .

К счастью, можно изменить поведение оболочки используя встроенные функции, в частности set. С ее помощью, можно значительно повысить безопасность.

set -e

Указав параметр -e скрипт немедленно завершит работу, если любая команда выйдет с ошибкой. По-умолчанию, игнорируются любые неудачи и сценарий продолжет выполнятся. Если предполагается, что команда может завершиться с ошибкой, но это не критично, можно использовать пайплайн || true .

#!/bin/bash ./non-existing-command echo "RUNNING" # output # ------ # line 3: non-existing-command: command not found # RUNNING 

С использованием -e :

#!/bin/bash set -e ./non-existing-command || true ./non-existing-command echo "RUNNING" # output # ------ # line 4: non-existing-command: command not found # line 5: non-existing-command: command not found 

set -o pipefail

Но -e не идеален. Bash возвращает только код ошибки последней команды в пайпе (конвейере). И параметр -e проверяет только его. Если нужно убедиться, что все команды в пайпах завершились успешно, нужно использовать -o pipefail .

#!/bin/bash set -e ./non-existing-command | echo "PIPE" echo "RUNNING" # output # ------ # PIPE # line 4: non-existing-command: command not found # RUNNING 

С использованием -o pipefail :

#!/bin/bash set -eo pipefail ./non-existing-command | echo "PIPE" echo "RUNNING" # output # ------ # PIPE # line 4: non-existing-command: command not found 

set -u

Наверно самый полезный параметр — -u . Благодаря ему оболочка проверяет инициализацию переменных в скрипте. Если переменной не будет, скрипт немедленно завершиться. Данный параметр достаточно умен, чтобы нормально работать с переменной по-умолчанию $ и условными операторами ( if , while , и др).

#!/bin/bash echo "$MY_VAR>" echo "RUNNING" # output # ------ # # RUNNING 

С использованием -u :

#!/bin/bash set -u echo "$MY_VAR>" echo "RUNNING" # output # ------ # line 4: MY_VAR: unbound variable 

set -x

Параметр -x очень полезен при отладке. С помощью него bash печатает в стандартный вывод все команды перед их исполнением. Стоит учитывать, что все переменные будут уже доставлены, и с этим нужно быть аккуратнее, к примеру если используете пароли.

#!/bin/bash MY_VAR="a" echo "$MY_VAR>" echo "RUNNING" # output # ------ # a # RUNNING 

С использованием -x :

#!/bin/bash set -x echo "$MY_VAR>" echo "RUNNING" # output # ------ # + MY_VAR=a # + echo a # a # + echo RUNNING # RUNNING 

Вывод

Не стоит забывать, что все эти параметры можно объединять и комбинировать между собой! Думаю, при работе с bash будет хорошим тоном начинать каждый сценарий с set -euxo pipefail .

What does `set -x` do?

@Ole, set is built into bash so if you man bash you can find it in the SHELL BUILTIN COMMANDS section. When viewing the man page you can probably jump to it by searching for this regexp: \bset \[ .

Sep 28, 2018 at 17:10
man is for non-builtins and help is for shell builtins.
Feb 8, 2021 at 6:06

BTW, the string comparison operator should be = not == ; the latter is a nonstandard extension, the former is officially standardized and guaranteed to be available in all POSIX-compliant sh implementations.

Jun 26, 2023 at 19:37

3 Answers 3

set -x enables a mode of the shell where all executed commands are printed to the terminal. In your case it’s clearly used for debugging, which is a typical use case for set -x : printing every command as it is executed may help you to visualize the control flow of the script if it is not functioning as expected.

set +x disables it.

18.6k 27 27 gold badges 120 120 silver badges 169 169 bronze badges
answered Mar 29, 2016 at 1:07
John Zwinck John Zwinck
242k 38 38 gold badges 325 325 silver badges 439 439 bronze badges

This is VERY useful! I wish someone had told me that earlier. Are there other interesting tricks like this that can sort of boost up our meta-skill on scripting?

Jun 27, 2019 at 13:22

@Student: set -e at the top of your script will make the script exit with an error whenever an error occurs (and is not explicitly handled). I find that immensely preferable to the default, which is to keep going willy-nilly (like Visual Basic’s infamous On Error Resume Next ).

Jun 28, 2019 at 6:41

@JohnZwinck, unfortunately, set -e has very undesirable side effects, to the point that it makes code review almost impossible (because a given line’s behavior depends on what’s up the call stack — if a function is called in a «checked» context, set -e is disabled for that invocation and everything it in turn calls). See the exercises in BashFAQ #105.

Feb 16, 2020 at 3:49

@JohnZwinck, Yes, but I have no idea who rking is. Greycat is the author of the BashFAQ, the channel elder of the freenode IRC #bash channel, etc — if you’re going to argue-by-authority, it helps to know who the authorities in a field are. And yes, I absolutely do argue for tediously checking every command’s exit handling, just as a code review requires in C or Go, or any other language that doesn’t support exceptions. To rely on set -e is to rely on something that is simply not reliable.

Feb 16, 2020 at 19:23

btw: these messages are printed to stderr, so if you for example have such a script running inside a docker container, these messages are interpreted as errors. 🙂

Aug 10, 2020 at 12:56

$(set -x)

Prints a trace of simple commands, for commands, case commands, select commands, and arithmetic for commands and their arguments or associated word lists after they are expanded and before they are executed. The value of the PS4 variable is expanded and the resultant value is printed before the command and its expanded arguments.

Example

set -x echo $(expr 10 + 20) + expr 10 + 20 + echo 30 30 
set +x echo $(expr 10 + 20) 30 

Above example illustrates the usage of set -x . When it is used, above arithmetic expression has been expanded. We could see how a single line has been evaluated step by step.

  • First step expr has been evaluated.
  • Second step echo has been evaluated.

To know more about set → visit this link

when it comes to your shell script,

[ "$DEBUG" == 'true' ] && set -x 

Your script might have been printing some additional lines of information when the execution mode selected as DEBUG . Traditionally people used to enable debug mode when a script called with optional argument such as -d

answered Mar 29, 2016 at 7:08
2,902 8 8 gold badges 34 34 silver badges 57 57 bronze badges

Think about using $( ) instead of backticks when writing examples — it’s been part of the POSIX.2 standard since its initial publication in the early 1990s so there’s no meaningful portability loss, and it’s much better form (nests well, doesn’t change the meaning of backslashes contained within, &c).

Jun 26, 2023 at 19:39
Thanks for suggestion @CharlesDuffy, Agreed with your comment and I have updated the answer !
Jun 27, 2023 at 11:04

-u: disabled by default. When activated, an error message is displayed when using an unconfigured variable.

-v: inactive by default. After activation, the original content of the information will be displayed (without variable resolution) before the information is output.

-x: inactive by default. If activated, the command content will be displayed before the command is run (after variable resolution, there is a ++ symbol).

Compare the following differences:

/ # set -v && echo $HOME /root / # set +v && echo $HOME set +v && echo $HOME /root / # set -x && echo $HOME + echo /root /root / # set +x && echo $HOME + set +x /root / # set -u && echo $NOSET /bin/sh: NOSET: parameter not set / # set +u && echo $NOSET 

Bash set x что это

Необязательные параметры — это дополнительные ключи (опции), которые оказывают влияние на поведение сценария и/или командной оболочки.

Команда set позволяет задавать дополнительные опции прямо внутри сценария. В том месте сценария, где необходимо, чтобы та или иная опция вступила в силу, вставьте такую конструкцию set -o option-name, или в более короткой форме — set -option-abbrev. Эти две формы записи совершенно идентичны по своему действию.

#!/bin/bash set -o verbose # Вывод команд перед их исполнением.
#!/bin/bash set -v # Имеет тот же эффект, что и выше.

Для того, чтобы отключить действие той или иной опции, следует вставить конструкцию set +o option-name, или set +option-abbrev.

#!/bin/bash set -o verbose # Вывод команд перед их исполнением. command . command set +o verbose # Запретить вывод команд перед их исполнением. command # команда не выводится. set -v # Вывод команд перед их исполнением. command . command set +v # Запретить вывод команд перед их исполнением. command exit 0

Как вариант установки опций, можно предложить указывать их в заголовке сценария (в строке sha-bang) — #!.

#!/bin/bash -x # # Далее следует текст сценария.

Так же можно указывать дополнительные ключи в командной строке, при запуске сценария. Некоторые из опций работают только если они заданы из командной строки, например -i — ключ интерактивного режима работы скрипта.

bash -v script-name

bash -o verbose script-name

Ниже приводится список некоторых полезных опций, которые могут быть указаны как в полной форме так и в сокращенной.

Таблица 30-1. Ключи Bash

Назад К началу Вперед
Отладка сценариев Наверх Широко распространенные ошибки

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *