Ответ 1
FOO=bar bash -c 'somecommand someargs | somecommand2'
В данной оболочке, как правило, я бы установил переменную или переменные, а затем запустил команду. Недавно я узнал о концепции добавления определения переменной в команду:
FOO=bar somecommand someargs
Это работает... вроде. Это не работает, когда вы меняете переменную LC_ * (которая, кажется, влияет на команду, но не ее аргументы, например, "[az]" char диапазоны) или когда вывод трубопровода на другую команду:
FOO=bar somecommand someargs | somecommand2 # somecommand2 is unaware of FOO
Я могу добавить somecommand2 с "FOO = bar", который работает, но который добавляет нежелательное дублирование, и это не помогает с аргументами, которые интерпретируются в зависимости от переменной (например, "[az]" )
Итак, какой хороший способ сделать это в одной строке? Я думаю что-то по порядку:
FOO=bar (somecommand someargs | somecommand2) # Doesn't actually work
Изменить: у меня много хороших ответов! Цель состоит в том, чтобы сохранить это однострочное изображение, предпочтительно без использования "экспорта". Метод, использующий вызов bash, был лучшим в целом, хотя скобковая версия с "export" в нем была немного более компактной. Интересен также метод использования перенаправления, а не трубы.
FOO=bar bash -c 'somecommand someargs | somecommand2'
Как экспортировать переменную, но только внутри подоболочки?:
(export FOO=bar && somecommand someargs | somecommand2)
У Keith есть точка для безусловного выполнения команд:
(export FOO=bar; somecommand someargs | somecommand2)
Вы также можете использовать eval
:
FOO=bar eval 'somecommand someargs | somecommand2'
Поскольку этот ответ с eval
, похоже, не радует всех, позвольте мне пояснить кое-что: при использовании в качестве письменного, с одинарными кавычками, это совершенно безопасно. Это хорошо, поскольку он не запускает внешний процесс (например, принятый ответ) и не выполняет команды в дополнительной подоболочке (как и другой ответ).
Как мы получим несколько регулярных представлений, вероятно, полезно дать альтернативу eval
, которая понравится всем, и имеет все преимущества (и, возможно, даже больше!) этого быстрого трюка eval
. Просто используйте функцию! Определите функцию со всеми вашими командами:
mypipe() {
somecommand someargs | somecommand2
}
и выполните его с такими переменными среды, как это:
FOO=bar mypipe
Обновление: это неправильно, и я скоро удалю ответ.
Я считаю, что это невозможно сделать, не называя "bash -c" (например, творческое использование круглых скобок)?
for FOO in bar; do echo $FOO; done # put somecommand someargs instead of echo
Хотя это может вызвать тревогу у новичков, это супер чисто, потому что между вашими командами и текущей оболочкой нет bash -c
, либо с помощью скобок или bash -c
либо каким-либо другим способом.
Единственным недостатком по сравнению с префиксом FOO=bar cmd
является необходимость завершить done
но это довольно тривиальный недостаток, учитывая, что для всех других решений требуется подселлед, чтобы вызвать команду.
Используйте env
.
Например, env FOO=BAR command
. Обратите внимание, что переменные среды будут восстановлены/неизменны снова, когда command
завершит выполнение.
Просто будьте осторожны с заменой оболочки, т.е. Если вы хотите явно указать $FOO
в той же командной строке, вам может понадобиться экранировать ее, чтобы ваш интерпретатор оболочки не выполнил подстановку до env
.
$ export FOO=BAR
$ env FOO=FUBAR bash -c 'echo $FOO'
FUBAR
$ echo $FOO
BAR
Как насчет использования оболочки script?
#!/bin/bash
# myscript
FOO=bar
somecommand someargs | somecommand2
> ./myscript