Оказывается, существует очень конкретная причина такого поведения.
Описание происходящего немного длиннее.
Командная строка, созданная (только) из назначений, устанавливает переменные для этой оболочки.
$ unset a b c d
$ a=b c=d
$ echo "<$a::$c>"
Значение назначенных переменных будет сохранено.
Присваивания перед внешней командой устанавливают переменные для , только для оболочки:
$ unset a b c d
$ a=b c=d bash -c 'echo "one:|$c|"'; echo "two:<$c>"
one:|d|
two:<>
И я имею в виду «внешнюю» как любую команду, которую нужно искать в PATH.
Это также относится к обычным встроенным программам (например, cd):
$ unset a b c d; a=b c=d cd . ; echo "<$a::$c>"
<::>
Здесь все, как обычно, ожидается.
Но для специальных встроенных модулей POSIX требует, чтобы значения были установлены для этой оболочки .
- Назначения переменных, указанные с помощью специальных встроенных утилит , остаются в силе после завершения встроенной функции.
$ sh -c 'unset a b c d; a=b c=d export f=g ; echo "<$a::$c::$f>"'
Я использую вызов sh
, предполагая, что sh
является POSIX-совместимой оболочкой.
Это не то, что обычно используется.
Это означает, что назначения, помещенные перед любым из этого списка специальных встроенных модулей, должны сохранять присвоенные значения в текущей запущенной оболочке:
break : continue . eval exec exit export
readonly return set shift times trap unset
Это произойдет, если оболочка работает согласно спецификации POSIX.
Можно установить переменные только для одной команды, любой команды, убедившись, что команда не является специальной встроенной. Команда команда
является обычной встроенной. Он только указывает оболочке использовать команду, а не функцию. Эта строка работает во всех оболочках (кроме ksh93):
$ unset a b c d; a=b c=d command eval 'f=g'; echo "<$a::$c::$f>"
<::::g>
В этом случае переменные a и b устанавливаются для среды выполнения команды и после этого удаляются.
Вместо этого будут сохранены присвоенные значения (кроме bash и zsh):
$ unset a b c d; a=b c=d eval 'f=g'; echo "<$a::$c::$f>"
Обратите внимание , что присвоение после eval заключено в одинарные кавычки, чтобы защитить его от нежелательных расширений.
Итак: Чтобы поместить переменные в командную среду, используйте команду eval
:
Изman cut
:
-d, --delimiter=DELIM
use DELIM instead of TAB for field delimiter
-f, --fields=LIST
select only these fields; also print any line that contains no delimiter character, unless the -s option is specified
Итак, вы разбиваете вывод по каждому символу-разделителю, в вашем случае по пробелу. Это создает массив полей. Параметр -f
указывает, что cut должен возвращать только 10-е поле.
Это из-за разделителя, который мы используем, у нас есть 8 пробелов передether
Мы можем проверить это, используя приведенный ниже код.
ifconfig enp3s0f2 | grep ether | sed 's/ether.*//' |grep -o ' ' | wc -l
8
Итак, 9-е поле — ether
, а 10-е поле —00:90:f5:e5:e4:7c