eval 與管道指令一起使用

eval 與管道指令一起使用

我有 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// zshksh source

source ./file

(請注意,新增 很重要./。否則,在考慮當前目錄中的之前先source查找filein 。如果在 POSIX 模式下,甚至不會考慮當前目錄中的 ,即使在 中 沒有找到)。$PATHfilebashfile$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,只需使用awkorperl的系統指令:

// 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

(我意識到這是一個老問題。)

相關內容