команды скрипта bash, разделенные пробелом

Perl имеет специальный режим параграфов, в котором он определяет «строки» как параграфы. Это означает, что строка определяется двумя последовательными \ n , а не одним. Из man perlrun :

   -0[octal/hexadecimal]
        specifies the input record separator ($/) as an octal or
        hexadecimal number. [. . .]

    The special value 00 will cause Perl to slurp files in paragraph
    mode.  

Таким образом, вы можете написать сценарий perl, который печатает ваши переменные:

$ perl -00lne '/.*/; $v=$&; $v=~s/-/_/g; print "$v=\"$_\""' file 
acpitz_virtual_0="acpitz-virtual-0
Adapter: Virtual device
temp1:        +41.0°C  (crit = +95.0°C)"

coretemp_isa_0000="coretemp-isa-0000
Adapter: ISA adapter
Core 0:       +36.0°C  (high = +90.0°C, crit = +90.0°C)
Core 1:       +36.0°C  (high = +90.0°C, crit = +90.0°C)"

А затем использовать eval , чтобы указать вашей оболочке прочитать их:

$ eval "$(perl -00lne '/.*/; $v=$&; $v=~s/-/_/g; print "$v=\"$_\""' file )"
$ echo "$coretemp_isa_0000"
coretemp-isa-0000
Adapter: ISA adapter
Core 0:       +36.0°C  (high = +90.0°C, crit = +90.0°C)
Core 1:       +36.0°C  (high = +90.0°C, crit = +90.0°C)

Сценарий Perl может потребовать некоторых пояснений. Здесь то же самое, что и сценарий с комментариями:

## The . doesn't match newlines by default, so this is just a 
## quick way of getting the text before the first \n, this will be
## you variable's name.
/.*/; 
## $& is whatever was matched my the last match (//) operator. We set
## $v to that.
$v=$&; 
## Bash doesn't like dashes in variable names, this will replace
## them with underscores. 
$v=~s/-/_/g; 
## Print the variable name and its value ($foo="bar")
print "$v=\"$_\""
-2
26.07.2018, 10:15
2 ответа

Итак, я думаю, что здесь вас сбивает с толку формат команды, в котором первое слово (и )в команде являются назначением переменной (, которое оболочка определяет на основе наличия =.)

В таких случаях оболочка оценит эти назначения, но только экспортирует эти переменные в выполняемой команде. В частности, сама оболочка не будет иметь доступа к этим переменным.

Это полезно для запуска команд или сценариев, на которые влияют переменные среды, и в этом случае вам не нужно экспортировать их в оболочку, и вы можете просто установить их как «один -offs» для этого единственного выполнения.

Давайте разберем ваши команды и объясним их одну за другой:

pwd echo 'aaa'                     # /home/me

Итак, это запуск команды pwdи передача ей двух аргументов, echoи aaa. Но pwdне принимает аргументов, поэтому он просто игнорирует эти два параметра и печатает локальный каталог.

val=pwd echo 'aaa'                 # aaa

Итак, как я объяснил, это выполняет присвоение переменной, устанавливая $valдля содержания строки pwd, а затем выполняет команду echoс аргументом aaa. Переменная $valдоступна только для команды echo, а не для самой оболочки! Команда echoна самом деле ничего не делает с этой переменной, поэтому она просто выводит aaa. После завершения этой команды переменная $valстановится , а не , определенной в оболочке.

val=pwd echo 'aaa'$val             # aaa

Итак, снова аналогично команде выше. Это становится сложным, так как вы можете ожидать, что окончательный $valбудет расширен. Но переменные расширяются оболочкой , а не командами. И, как объяснено, оболочка на самом деле не видит $val, для которого установлено значение pwd, только команда (, в данном случае echo), видит, поэтому $valрасширяется до пустой строки, и это точно эквивалентно вышеизложенному.

val=pwd echo 'aaa' && echo $val    # aaa <and an empty line>

И еще раз,$valнедоступен после завершения первой команды echo, поэтому вторая echo $valничего не напечатает (только пустую строку ), так как $valникогда не устанавливался в самой оболочке на протяжении всего этого выполнения.

Если вы хотите установить $valв оболочке, вам нужно сделать это назначение автономным, без каких-либо команд. Например, это ведет себя иначе, чем выше:

$ val=pwd; echo 'aaa' && echo $val
aaa
pwd

Поскольку за val=pwdследует ;, то оболочка считает это отдельной командой и установит $valв текущей оболочке, поэтому echo $valбудет работать так, как вы ожидаете.

(Обратите внимание, что здесь есть еще одно отличие, так как с val=pwd;...переменная $valна самом деле не экспортируется, поэтому echoне не увидит эту переменную в своем окружении, тогда как с val=pwd echo...он будет экспортирован , но в этом случае он недоступен в оболочке.)

И, учитывая, что вы используете pwd, интересно, вы хотели сохранить вывод этой команды в переменной... В этом случае вам нужно использовать подстановку команд оболочки , либо используя обратные кавычки, либо, что еще лучше, окружив команду $(и ).

Итак, последний пример здесь:

$ val=$(pwd); echo 'aaa' && echo $val
aaa
/home/me

Или:

$ val=$(pwd) && echo 'aaa' && echo $val
aaa
/home/me

(Здесь есть тонкая разница, где последний прервет выполнение, если команда внутри подстановки, в данном случае pwd, завершится ошибкой и выйдет с ненулевым статусом -, и в этом случае следующие команды не будут выполняться. казнен. При использовании ;это не так, следующие команды выполняются, даже если первая не удалась.)

Надеюсь, это объясняет, чего вы не понимали в этих командах!

9
28.01.2020, 05:14

приведенный ниже код может помочь понять, как работает эта конструкция:

$ cd tmprun/
$ cat run.sh 
echo $a
$./run.sh 

$ a=bla./run.sh 
bla
0
03.11.2021, 14:30

Теги

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