Как выполнить вывод команды в текущей оболочке?
Я хорошо осведомлен о source
(Он же .
) утилита, которая будет принимать содержимое из файла и выполнять их в текущей оболочке.
теперь я преобразую некоторый текст в команды оболочки, а затем запускаю их следующим образом:
$ ls | sed ... | sh
ls
это просто случайный пример, исходный текст может быть любым. sed
тоже, просто пример для преобразования текста. Интересный бит-это sh
. Я трубу все, что я получил sh
и он работает оно.
моя проблема в том, что это означает запуск новой суб оболочки. Я бы предпочел, чтобы команды выполнялись в моей текущей оболочке. Как я мог бы сделать с source some-file
, если бы у меня были команды в текстовый файл.
Я не хочу создавать временный файл, потому что чувствует себя грязным.
кроме того, я хотел бы начать свою суб-оболочку с теми же характеристиками, что и моя текущая оболочка.
обновление
ОК, решения, использующие backtick конечно работа, но мне часто нужно делать это, пока я проверяю и изменяю вывод, поэтому я бы предпочел, чтобы в конце концов был способ передать результат во что-то.
грустно обновления
а,/dev/stdin
это выглядело так красиво, но, в более сложном случае, это не сработало.
Итак, у меня есть это:
find . -type f -iname '*.doc' | ack -v '.doc$' | perl -pe 's/^((.*).doc)$/git mv -f .doc/i' | source /dev/stdin
которая гарантирует все .doc
файлы имеют расширение в нижнем регистре.
и с которым кстати, можно справиться xargs
, но это к делу не относится.
find . -type f -iname '*.doc' | ack -v '.doc$' | perl -pe 's/^((.*).doc)$/ .doc/i' | xargs -L1 git mv
Итак, когда я запускаю первый, он сразу же выйдет, ничего не происходит.
9 ответов:
$ ls | sed ... | source /dev/stdin
обновление: это работает в bash 4.0, а также tcsh и dash (если вы измените
source
to.
). По-видимому, это было багги в bash 3.2. Из bash 4.0 примечания к выпуску:Исправлена ошибка, приводившая `.'не читать и не выполнять команды из нерегулярных файлов, таких как устройства или именованные каналы.
The
eval
команда существует именно для этой цели.eval "$( ls | sed... )"
больше bash manual:
eval
eval [arguments]
аргументы объединены вместе в единую команду, которая затем читается и выполняется, и его статус выхода возвращается как выход статус eval. Если нет аргументы или только пустые аргументы, статус возврата равен нулю.
Ничего себе, Я знаю, что это старый вопрос, но я нашел себя с той же самой проблемой в последнее время (вот как я попал сюда).
в любом случае - мне не нравится
source /dev/stdin
ответ,но я думаю, что нашел лучший. Это обманчиво просто на самом деле:echo ls -la | xargs xargs
приятно, правда? На самом деле, это все еще не делает то, что вы хотите, потому что если у вас есть несколько строк, он объединит их в одну команду вместо того, чтобы запускать каждую команду отдельно. Так что решение я нашел это:
ls | ... | xargs -L 1 xargs
the
-L 1
опция означает, что вы используете (не более) 1 строку на выполнение команды. Примечание: если ваша строка заканчивается конечным пробелом, она будет объединена со следующей строкой! Поэтому убедитесь, что каждая строка заканчивается не пробелом.наконец, вы можете сделать
ls | ... | xargs -L 1 xargs -t
чтобы увидеть, какие команды выполняются (-Т многословен).
надеюсь, что кто-то читает это!
попробуйте использовать подмена процесса, который заменяет вывод команды временным файлом, который затем может быть получен:
source <(echo id)
Я считаю, что это "правильный ответ" на вопрос:
ls | sed ... | while read line; do $line; done
то есть, можно трубить в
while
loop; theread
команда команда берет одну строку из егоstdin
и присваивает его переменной$line
.$line
затем становится командой, выполняемой в цикле; и она продолжается до тех пор, пока на ее входе не будет больше строк.это все равно не будет работать с некоторыми структурами управления (например, с другим циклом), но в этом случае это соответствует счету.
`ls | sed ...`
Я вроде как чувствую себя
ls | sed ... | source -
было бы красивее, но, к сожалению,source
не понимаю-
означаетstdin
.
Я думаю, что ваше решение-это замена команды с помощью обратных кавычек:http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_04.html
см. раздел 3.4.5