我有 file.txt ,命令儲存在一行中(該命令在控制台中運行時有效),我想用 sh 在一行中執行它
cat file.txt | eval
缺什麼?有什麼建議嗎?
如果我的文件包含許多命令(每行一個)並且我只想執行一個命令(一整行)怎麼辦?我的第一個想法是:
head -n5 | tail -n1 | eval
答案1
eval
不從標準輸入讀取其命令字串。
eval "$(cat file.txt)"
# or easier, in ksh/bash/zsh
eval "$(<file.txt)"
# usually you cannot be sure that a command ends at the end of line 5
eval "$(head -n 5 file.txt)"
相反,如果命令位於文件中,則eval
可以使用標準.
或bash
// zsh
:ksh
source
source ./file
(請注意,新增 很重要./
。否則,在考慮當前目錄中的之前先source
查找file
in 。如果在 POSIX 模式下,甚至不會考慮當前目錄中的 ,即使在 中 沒有找到)。$PATH
file
bash
file
$PATH
當然,這不適用於選擇文件的一部分。這可以透過以下方式完成:
head -n 5 file.txt >commands.tmp
source ./commands.tmp
或(使用 ksh93、zsh、bash):
source <(head -n 5 file.txt)
答案2
所以...你的問題的解決方案是 100% 可能的,並且(在 的背景下make
)很重要。
我用 makefile 遇到了這個問題,考慮到在已經用於呼叫變數的 makefile 中嵌套 bash 命令的困難$(...)
,能夠準確地執行您所要求的操作是很好的。
不使用eval
,只需使用awk
orperl
的系統指令:
// command_list.sh:
echo "1"
echo "2"
echo "3"
// command line prompt:
$: cat command_list.sh | awk '{system($0)}'
1
2
3
並且,指揮大樓:
// a readable version--rather than building up an awk miniprogram,
// split into logical blocks:
$: cat inputs.txt | awk '{print "building "$1" command "$2" here "}' | awk '{system($0)}'
答案3
從技術上講,如果您想從管道中讀取某些內容,則不可能評估當前環境中的某些內容,因為管道中的每個命令都作為單獨的進程執行。
但是,根據您想要實現的目標,這可能並不重要。無論如何,這裡是eval
針對管道的內容運行的:
❯ echo echo hi | eval "$(cat -)"
hi
這是一個捕獲的例子。類似下面的內容不會列印1
:
❯ echo a=1 | eval "$(cat -)"; echo $a
我們必須執行以下操作:
❯ echo a=1 | { eval "$(cat -)"; echo $a; }
1
答案4
如果您不確定使用eval
,請使用sh
:
cat file.txt | sh
是的,它將在單獨的 sh 實例中運行,但這一事實是自我記錄的。
還有while read
:
cat file.txt | while read cmd; do eval $cmd; done
執行file.txt第5行命令:
sed -n 5p file.txt | sh
(我意識到這是一個老問題。)