如何在POSIX shell中对双引号字符串进行迭代? [英] How to iterate over double-quoted strings in POSIX shell?
问题描述
我正在尝试检查脚本所依赖的所有非POSIX命令是否都存在,然后我的脚本才能继续执行其主要工作.这将有助于我确保脚本以后不会由于缺少命令而生成错误.
I am trying to check if all the non POSIX commands that my script depends on are present before my script proceeds with its main job. This will help me to ensure that my script does not generate errors later due to missing commands.
我想将所有这些非POSIX命令的列表保存在一个名为DEPS
的变量中,以便随着脚本的发展以及依赖于更多命令的需要,我可以编辑该变量.
I want to keep the list of all such non POSIX commands in a variable called DEPS
so that as the script evolves and depends on more commands, I can edit this variable.
我希望脚本支持其中带有空格的命令,例如my program
.
I want the script to support commands with spaces in them, e.g. my program
.
这是我的脚本.
#!/bin/sh
DEPS='ssh scp "my program" sftp'
for i in $DEPS
do
echo "Checking $i ..."
if ! command -v "$i"
then
echo "Error: $i not found"
else
echo "Success: $i found"
fi
echo
done
但是,这是行不通的,因为在for
循环迭代时,"my program"
被分为两个单词:"my
和program"
,如下面的输出所示.
However, this doesn't work, because "my program"
is split into two words while the for
loop iterates: "my
and program"
as you can see in the output below.
# sh foo.sh
Checking ssh ...
/usr/bin/ssh
Success: ssh found
Checking scp ...
/usr/bin/scp
Success: scp found
Checking "my ...
Error: "my not found
Checking program" ...
Error: program" not found
Checking sftp ...
/usr/bin/sftp
Success: sftp found
我期望的输出是:
# sh foo.sh
Checking ssh ...
/usr/bin/ssh
Success: ssh found
Checking scp ...
/usr/bin/scp
Success: scp found
Checking my program ...
Error: my program not found
Checking sftp ...
/usr/bin/sftp
Success: sftp found
如何在保持脚本POSIX兼容的同时解决此问题?
How can I solve this problem while keeping the script POSIX compliant?
推荐答案
我将重复对上一个问题的回答:对while文档使用while循环,而不是for循环.您可以在字符串中嵌入换行符,如果这些命令名中可能包含空格,则只需要将命令名分隔在字符串中即可. (如果您的命令名称包含换行符,请强烈考虑重命名它们.)
I'll repeat the answer I gave to your previous question: use a while loop with a here document rather than a for loop. You can embed newlines in a string, which is all you need to separate command names in a string if those command names might contain whitespace. (If your command names contain newlines, strongly consider renaming them.)
要获得最大的POSIX兼容性,请使用printf
,因为echo
的POSIX规范非常松懈,这是由于在定义标准之前在各种shell中实现echo
的方式有所不同.
For maximum POSIX compatibility, use printf
, since the POSIX specification of echo
is remarkably lax due to differences in how echo
was implemented in various shells prior to the definition of the standard.
deps="ssh
scp
my program
sftp
"
while read -r cmd; do
printf "Checking $cmd ...\n"
if ! command -v "$cmd"; then
printf "Error: $i not found\n"
else
printf "Success: $cmd found\n"
fi
printf "\n"
done <<EOF
$deps
EOF
这篇关于如何在POSIX shell中对双引号字符串进行迭代?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!