Вдохновленный комментариями mikeserv, я сейчас делаю это с помощью команды
node --version | cut -d. -f1 | cut -c2-
. Здесь используется cut с .
разделитель для извлечения только строки v
. Затем он снова использует команду cut, чтобы взять все символы, начиная со второго, что удаляет v
.
Здесь используются только coreutils (кроме node
), что делает его максимально переносимым.
Команда, запускаемая eval
, выполняется в текущей оболочке, а команда, переданная в bash
, выполняется в подчиненной оболочке -, например.:
> echo 'x=42' | bash; echo $x
> eval 'x=42'; echo $x
42
В комментариях утверждалось, что в более поздних версияхbash
(>=4.2 )первая команда также могла иметь такой же эффект. Однако, похоже, это не так.
На самом деле есть пара факторов, из-за которых конвейерная команда не запускается в текущем сеансе :конвейера и команды bash
.
По большей части конвейерные команды выполняются в подоболочках. Руководство Bash(Раздел 3.2.2 :Трубопроводы)говорит следующее:
Each command in a pipeline is executed in its own subshell (see Command Execution Environment).
Как указано в комментариях, это поведение можно изменить с помощью параметра lastpipe
. Руководство Bash (, раздел 4.3.2 :Встроенная программа Shopt)говорит следующее об опции lastpipe
:
lastpipe
If set, and job control is not active, the shell runs the last command of a pipeline not executed in the background in the current shell environment.
Мы можем проверить, что это так, следующим образом.
Первое включениеlastpipe
:
> shopt -s lastpipe
Затем отключите управление заданием -:
> set +m
Теперь выполните команду, которая устанавливает переменную внутри канала:
> unset x
> echo x=42 | while IFS= read -r line; do eval "${line}"; done;
> echo $x
42
Обратите внимание, что мы используем цикл while
и команду read
в качестве обходного -, так как команда eval
не может считывать ввод со стандартного ввода (, следовательно, не может получать ввод из конвейера ).
Этот пример демонстрирует, что самая правая -команда в конвейере может фактически выполняться в текущей оболочке. Однако на самом деле это не влияет на наш исходный пример. Даже при включенном lastpipe
и отключенном управлении заданием -мы все равно получаем следующий результат при передаче вbash
:
> echo 'x=42' | bash; echo $x
>
Это связано с тем, что сама команда bash
выполняет ввод в подоболочке.