Во-первых, я боюсь, что объяснение варианта -o
, обслуживаемого http://explainshell.com, не совсем корректно.
Учитывая, что set
является булитой -в команду, мы можем увидеть ее документацию с помощью help
, выполнивhelp set
:
-o option-name
Set the variable corresponding to option-name:
allexport same as -a
braceexpand same as -B
emacs use an emacs-style line editing interface
errexit same as -e
errtrace same as -E
functrace same as -T
hashall same as -h
histexpand same as -H
history enable command history
ignoreeof the shell will not exit upon reading EOF
interactive-comments
allow comments to appear in interactive commands
keyword same as -k
monitor same as -m
noclobber same as -C
noexec same as -n
noglob same as -f
nolog currently accepted but ignored
notify same as -b
nounset same as -u
onecmd same as -t
physical same as -P
pipefail the return value of a pipeline is the status of
the last command to exit with a non-zero status,
or zero if no command exited with a non-zero status
posix change the behavior of bash where the default
operation differs from the Posix standard to
match the standard
privileged same as -p
verbose same as -v
vi use a vi-style line editing interface
xtrace same as -x
Как видите -o pipefail
означает:
the return value of a pipeline is the status of the last command to exit with a non-zero status, or zero if no command exited with a non-zero status
Но не сказано:Write the current settings of the options to standard output in an unspecified format.
Теперь -x
используется для отладки, как вы уже знаете, и -e
будет остановить выполнение после первой ошибки в скрипте. Рассмотрите сценарий вот так:
#!/usr/bin/env bash
set -euxo pipefail
echo hi
non-existent-command
echo bye
Строка echo bye
никогда не будет выполняться при использовании -e
, потому что non-existent-command
не возвращает 0:
+ echo hi
hi
+ non-existent-command
./setx.sh: line 5: non-existent-command: command not found
Без -e
последняя строка будет напечатана, потому что даже если произошла ошибка, мы не указали Bash
автоматически выйти:
+ echo hi
hi
+ non-existent-command
./setx.sh: line 5: non-existent-command: command not found
+ echo bye
bye
set -e
часто помещают в начало сценария, чтобы убедиться, что сценарий будет остановлен, когда будет обнаружена первая ошибка -для например, если загрузка файла не удалась, нет смысла извлекать Это.
Если первым символом переменной IFS является пробел (, который по умолчанию равен ), вы можете использовать звездочку в двойных кавычках.
#! /bin/bash
arr[0]=2019-06-26
arr[1]=15:21:54
string="${arr[*]}"
printf "'%s'" "$string"
Задокументировано в Специальные параметры:
When the expansion occurs within double quotes, it expands to a single word with the value of each parameter separated by the first character of the IFS special variable.
Для полноты картины, хотя синтаксис "${array[*]}"
Korn (, расширенный из специального параметра Bourne "$*"
), также будет работать в zsh, в zsh вы можете использоватьj
(для флаг расширения параметра join ), который позволяет использовать любую произвольную строку соединения и не требует использования глобального параметра, такого как$IFS
:
$ a=(foo bar)
$ echo ${(j[:::])a}
foo:::bar
Обратите внимание, что для "${a[*]}"
,ksh
(и ksh93, и mksh )соединяются по первому байту из $IFS
вместо первого символа. Это имеет значение для многобайтовых символов -, таких как:
$ ksh -c 'a=(foo bar); IFS="⇅"; echo "${a[*]}"'
foo�bar
$ mksh -c 'a=(foo bar); IFS="⇅"; echo "${a[*]}"'
foo�bar
$ mksh -o utf8-mode -c 'a=(foo bar); IFS="⇅"; echo "${a[*]}"'
foo�bar
(где это �
— это то, как мой эмулятор терминала визуализировал первый байт (0xe2 )этого символа ⇅
, который сам по себе не является допустимым символом ).
Другие оболочки типа Korn -с поддержкой массивов допустимы:
$ bash -c 'a=(foo bar); IFS="⇅"; echo "${a[*]}"'
foo⇅bar
$ zsh -c 'a=(foo bar); IFS="⇅"; echo "${a[*]}"'
foo⇅bar
$ yash -c 'a=(foo bar); IFS="⇅"; echo "${a[*]}"'
foo⇅bar