Shell-Script
如何在 sh -c 中執行循環
我無法理解使用
sh -c
.比方說,我想執行 for 循環
for i in {1..4}; do echo $i; done
。就其本身而言,這很好用。如果我將它傳遞給eval
,我需要轉義$
:eval "for i in {1..4}; do echo \$i; done"
。但我不能使它適用於sh -c "[...]"
:$ sh -c "for i in {1..4}; do echo $i; done" 4 $ sh -c "for i in {1..4}; do echo \$i; done" {1..4} $ sh -c "for i in \{1..4\}; do echo \$i; done" {1..4} $ sh -c "for i in \{1..4\}\; do echo \$i\; done" sh: 1: Syntax error: end of file unexpected
我在哪裡可以找到有關此的更多資訊?
通常的智慧是
-c
在單引號內定義腳本(在 之後)。您需要使用的另一部分是{1..4}
構造有效的外殼:$ bash -c 'for i in {1..4}; do echo $i; done' # also work with ksh and zsh
讓它與破折號(你的
sh
)一起工作的一種替代方法是在你正在使用的 shell 上進行擴展(我假設你使用 bash 或 zsh 作為你的互動式 shell):$ dash -c 'for i do echo $i; done' mysh {1..4} 1 2 3 4
{1..4}
是一個 zsh 運算符,從csh
的{x,y}
大括號擴展運算符擴展而來,現在由其他一些 shell 支持,但它不是 POSIX sh 運算符(直到最近,POSIX 實際上需要echo {1..4}
輸出事件{1..4}
)。即使在 zsh 或其他現在支持
{x..y}
的 shell 中,它也不是執行循環增加整數變數的最佳方式,因為您最終分配了所有值的列表(此處僅適用於 4,但不能很好地擴展)。for i in $(seq 4)
(seq
不是標準命令)除了依賴$IFS
.在 ksh93、bash、zsh 中,使用:
for (( i = 1; i <= 4; i++ )); do printf '%s\n' "$i" done
一般認為比較好。它還允許負值,並更好地控制索引的遞增方式。
該
{x..y}
方法的優點是允許在多個範圍內循環,或在字母上循環,或使用填充(儘管根據外殼及其版本而有所不同):for i in {1..5} {9..12} x{0..3} {f..p} {001..0010}; do ... done
在
zsh
中,另見:i=; repeat 4 printf '%s\n' $((++i))
在 POSIX
sh
中,你會這樣做:i=1; while [ "$i" -le 4 ]; do printf '%s\n' "$i" i=$(( i + 1 )) done
或者:
sh -c ' i=1; while [ "$i" -le 4 ]; do printf "%s\n" "$i" i=$(( i + 1 )) done'
如果您需要一個新的
sh
呼叫,請從另一個 Bourne/rc/fish 之類的 shell 中執行該循環。當然,在這裡,你也可以這樣做:
for i in 1 2 3 4; do printf '%s\n' "$i" done