Я успешно выполнил команду 7z x <source.zip>
.
Версия:
p7zip Version 16.02 (locale=utf8,Utf16=on,HugeFiles=on,64 bits,[...])
Потенциально важная среда:
LANG=en_US.UTF-8
LC_ALL=en_US.UTF-8
LC_CTYPE=UTF-8
Он смог распаковать все файлы с 8 -битными символами в именах файлов, причем некоторые из этих символов были пропущены, а некоторые искажены.
тл;др; Я думаю, что это просто синтаксическая причуда, и вы не должны предполагать, что за этим стоит какой-то грандиозный замысел.
Bash использует сгенерированный bison/yacc -синтаксический анализатор , но, как и во многих других языках (C, perl и т. д. ), это не "чистый" синтаксический анализатор, а он также сохраняет некоторое состояние отдельно/параллельно грамматике в переменной parser_state
.
В этой переменной состояния хранится флаг PST_ASSIGNOK
. Это будет установлено, когда некоторые встроенные функции, которые были проанализированы как токен WORD
, имели ASSIGNMENT_BUILTIN
в своих флагах.
Такими "встроенными функциями назначения" являются local
, typeset
, declare
, alias
, export
и readonly
.
PST_ASSIGNOK
предписывает синтаксическому анализатору рассматривать круглые скобки как часть маркера WORD
, когда они используются после присваивания справа от такой встроенной функции. Но это НЕ изменит правила, которые определяют, является ли текущий токен на самом деле присвоением :. Поскольку ${foo}=(...)
не является приемлемым присвоением, оно не будет анализироваться как одно слово, а круглые скобки вызовут синтаксис ошибка точно так же, как в echo foo(bar)
.
После синтаксического анализа командной строки она будет расширена , и как часть расширений любое составное назначение (WORD
, помеченное как W_COMPASSIGN
), например var=(1 2)
, будет выполнено и заменено с var
, который затем будет передан в качестве аргумента встроенной функции, например declare
. Но если declare
после всех расширений получит аргумент вида var=(...)
, то он снова сам его разберет и расширит.
Итак, varname=foo; declare "$var=(1 2 3)"
может быть похоже на declare foo='(1 2 3)'
. Или к declare foo=(1 2 3)
, в зависимости от того, была ли переменная уже определена:
$ declare 'foo=(1 2 3)'; typeset -p foo
declare -- foo="(1 2 3)"
$ declare foo=(1); typeset -p foo
declare -a foo=([0]="1")
$ declare 'foo=(1 2 3)'; typeset -p foo
declare -a foo=([0]="1" [1]="2" [2]="3")
Я не думаю, что стоит полагаться на этот крайний случай:
$ declare 'bar=(1 ( )'; typeset -p bar
declare -- bar="(1 ( )"
$ declare bar=(1); typeset -p bar
declare -a bar=([0]="1")
$ declare 'bar=(1 ( )'; typeset -p bar
bash: syntax error near unexpected token `('