如何在POSIX shell中对双引号字符串进行迭代? [英] How to iterate over double-quoted strings in POSIX shell?

查看:56
本文介绍了如何在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"被分为两个单词:"myprogram",如下面的输出所示.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆