Преобразование переменной типа массива в строковый тип с разделителем пробелом

Во-первых, я боюсь, что объяснение варианта -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часто помещают в начало сценария, чтобы убедиться, что сценарий будет остановлен, когда будет обнаружена первая ошибка -для например, если загрузка файла не удалась, нет смысла извлекать Это.

2
28.06.2019, 22:33
2 ответа

Если первым символом переменной 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.

7
27.01.2020, 21:50

Для полноты картины, хотя синтаксис "${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
3
27.01.2020, 21:50

Теги

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