Попытка запустить сценарий .sh из curl

TL;DR :В случае export FOO=barbash вызывает создание временной среды, устанавливает FOO=barв этой среде, а затем выдает окончательную команду export FOO. В этот момент FOOпринимается в качестве последнего аргумента.


Ах, много -оскорбленных$_:

($_, an underscore.) At shell startup, set to the absolute pathname used to invoke the shell or shell script being executed as passed in the environment or argument list. Subsequently, expands to the last argument to the previous command, after expansion. Also set to the full pathname used to invoke each command executed and placed in the environment exported to that command. When checking mail, this parameter holds the name of the mail file.

Рассмотрим несколько вариантов:

$ man; echo $_
What manual page do you want?
man
$ man foo; echo $_
No manual entry for foo
foo
$ echo; echo $_

echo
$ echo bar foo; echo $_
bar foo
foo
$ foo=x eval 'echo $foo'; echo $_
x
echo $foo
$ bar() { man $1; }; echo $_
foo
$ for (( i=0; $i<0; i=i+1 )); do echo $i; done; echo $_
foo
$ bar; echo $_
What manual page do you want?
man
$ bar foo; echo $_
No manual entry for foo
foo
$ MANPATH=/tmp; echo $_

$ export MANPATH=/tmp; echo $_
MANPATH

Итак, мы видим здесь три модели:

  • Команды, вызываемые из файловой системы, функций и встроенных -ins, ведут себя так, как обычно ожидается:$_устанавливается на имя самой команды, если нет аргументов, в противном случае последний из представленных аргументов.
  • После определения функций, циклов и других логических конструкций:$_не изменяется.
  • Все остальное:$_настроено на что-то не совсем ожидаемое; странный.

Я доработал код, чтобы пролить свет на странности.

$./bash --noprofile --norc -c 'man foo'
lastword=[man]
lastarg=[foo]
$./bash --noprofile --norc -c 'export FOO=bar'
lastword=[export]
lastarg=[FOO=bar]
bind_variable, name=[FOO], value=[bar]
before bind_lastarg, lastarg=[FOO]
bind_lastarg, arg=[FOO]
bind_variable, name=[_], value=[FOO]
$./bash --noprofile --norc -c 'declare FOO=bar'
lastword=[declare]
lastarg=[FOO=bar]
bind_variable, name=[FOO], value=[(null)]
before bind_lastarg, lastarg=[FOO=bar]
bind_lastarg, arg=[FOO=bar]
bind_variable, name=[_], value=[FOO=bar]

Вы можете видеть, что анализатор видит ожидаемый последний аргумент(lastarg=)во всех случаях, но то, что происходит после этого, зависит от того, что, по мнению bash, должно произойти. См. выполнить _cmd.c,выполнить _простую _команду ().

В случае export FOO=barbash выполняет присваивание, а затем экспортирует переменную. Кажется, это согласуется с утверждением документации о том, что последний аргумент вычисляется после раскрытия.

1
21.02.2020, 22:39
1 ответ
curl https://example.com/script.sh | bash

Или sudo bash, если его нужно запустить от имени пользователя root.

0
28.04.2021, 23:22

Теги

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