Раскрытие фигурных скобок в Bash после косой черты пути

Для этого есть несколько решений - вы хотите сохранить ручное управление шагами и просто выполнять их одновременно? Посмотрите на CSSH (если вы используете систему Linux) или SuperPutty (если вы используете систему Windows). Если вы просто хотите все автоматизировать, посмотрите Ожидайте .

12
05.04.2018, 04:02
3 ответа

Синтаксис расширения скобок допускает запятые, но не допускает пробел после запятой. Во многих языках программирования пробелы после запятых являются обычным явлением, но не здесь. В Bash наличие пробела без кавычек препятствует раскрытию скобок.

Уберите пробел и все заработает:

cp ~/some/dir/{my-file-to-rename.bin,new-name-of-file.bin}

Хотя это и не обязательно, обратите внимание, что вы можете переместить конечный .binза фигурные скобки:

cp ~/some/dir/{my-file-to-rename,new-name-of-file}.bin

Если вы хотите проверить эффект расширения фигурных скобок, вы можете использовать echo, printf '%s 'илиprintfс любой строкой формата, которую вы предпочитаете, чтобы сделать это. (Лично я просто использую echoдля этого, когда работаю в Bash, потому что встроенная команда echoBash по умолчанию не расширяет escape-последовательности и, таким образом, достаточно хорошо подходит для проверки того, какая команда на самом деле будет работать. )Например:

ek@Io:~$ echo cp ~/some/dir/{my-file-to-rename,new-name-of-file}.bin
cp /home/ek/some/dir/my-file-to-rename.bin /home/ek/some/dir/new-name-of-file.bin
29
27.01.2020, 19:54

string{foo, bar}не является расширением фигурной скобки; это два слова string{foo,и bar}. Чтобы использовать раскрытие фигурных скобок, скобки должны находиться в одном слове. Вам придется либо удалить лишний пробел, если он вам не нужен, либо заключить его в кавычки, если он вам нужен:

$ printf "%s\n" aa{bb, cc}
aa{bb,
cc}
$ printf "%s\n" aa{bb,cc}
aabb
aacc
$ printf "%s\n" aa{bb," cc"}
aabb
aa cc
24
27.01.2020, 19:54

Bash обращается с этим пространством так же, как и с любым другим. Как IFS, внутренний разделитель полей. Это используется для разделения слов после расширения и для разделения строк на слова с помощью встроенной команды чтения.

The shell treats each character of IFS as a delimiter, and splits the results of the other expansions into words on these characters. If IFS is unset, or its value is exactly, the default, then sequences of,, and at the beginning and end of the results of the previous expansions are ignored, and any sequence of IFS characters not at the beginning or end serves to delimit words. If IFS has a value other than the default, then sequences of the whitespace characters space and tab are ignored at the beginning and end of the word, as long as the whitespace character is in the value of IFS (an IFS whitespace character). Any character in IFS that is not IFS whitespace, along with any adjacent IFS whitespace characters, delimits a field. A sequence of IFS whitespace characters is also treated as a delimiter. If the value of IFS is null, no word splitting occurs.
-bash(1)

Вставив разделитель без экранирования, вы сказали bash, что ваша команда и аргументы:

  1. "сп"
  2. "~/some/dir/{мой -файл -в -переименовать.bin,"
  3. "новое -имя -файла -file.bin}"

Если бы у вас были кавычки или escape-последовательность "\", вы бы:

  1. "сп"
  2. "~/some/dir/{мой -файл -в -переименовать.bin,\ новое -имя -из -file.bin}"

Что также не будет тем, что вы хотели, если только «новое -имя -из -file.bin» не является новым именем файла, которое вы хотели. Пространство включено. Поскольку сначала происходит расширение скобок, а затем расширение тильды, bash будет выполняться:

  1. "сп"
  2. "/path/to/home/some/dir/my -file -to -rename.bin"
  3. "/path/to/home/some/dir/\ new -name -of -file.bin"

Простое удаление пробела исправило бы все это.

-1
27.01.2020, 19:54

Теги

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