【问题标题】:How to execute multiple command after double pipes in shell script如何在shell脚本中的双管道后执行多个命令
【发布时间】:2023-03-31 06:57:01
【问题描述】:

我正在编写一个 Korn shell 脚本,其中有这样的功能

#!/bin/ksh
myfunc() {
    some_command1 || return 1
    some_command2 || return 1
    ...
}

换句话说,我将双管道放在返回语句后,以便在命令失败时函数立即返回。

但我也希望它在返回之前打印一些错误消息,我试过了

#!/bin/ksh
myfunc() {
    some_command1 || echo "error while doing some_command1"; return 1
    some_command2 || echo "error while doing some_command2"; return 1
    ...
}

但它不起作用,无论some_command1成功或失败,第一个return语句总是被执行。

还有

#!/bin/ksh
myfunc() {
    some_command1 || (echo "error while doing some_command1"; return 1)
    some_command2 || (echo "error while doing some_command2"; return 1)
    ...
}

也不起作用,它似乎只从子进程而不是函数返回,并且无论some_command1成功还是失败,some_command2都会被执行。

有没有办法对语句echo "error while doing some_command2"; return 1 进行分组,这样它们只有在前面的命令失败时才会一起执行。

【问题讨论】:

  • { cmd1; cmd2; } 也许?
  • 我喜欢那个函数的风格——首先排除异常,避免嵌套 ifs。

标签: shell unix ksh


【解决方案1】:

最直接的方法是使用{ ...; ...; },它结合了命令而不创建子shell。

some_command1 ||
    { echo "error while doing some_command1"; return 1; }

不过,我确实建议使用 stderr 来获取错误消息:

some_command1 ||
    { echo "error while doing some_command1" >& 2; return 1; }

因为我可以,我会给你我的秘密捷径:

some_command1 ||
    return 1 $(echo "error while doing some_command1" >& 2)

最后一点是非常规的,但仍然是可移植的 POSIX shell。

【讨论】:

  • 不知何故解决方案#1 和#2 对我不起作用,它就像不存在花括号一样,并且总是执行return 1。但是#3 就像一个魅力。
  • 对不起,我刚刚弄清楚为什么解决方案 #1 和 #2 对我不起作用,这是因为我这样写:{echo "444"; return 1} return 1 后面没有分号。这使得 return 语句每次都执行
  • @asinkxcoswt,{} 必须 周围有空格。见gnu.org/software/bash/manual/bashref.html#Command-Grouping
  • @asinkxcoswt 正如 Glenn 所说,(...){ ... } 不可互换,因为括号 不需要 需要任何空格,而花括号则需要。 @glennjackman 一如既往,感谢您提供的详细信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多