如何在 shell 函数中获得“set -e”的效果和用处?

2024-04-24

set -e(或以#!/bin/sh -e)对于出现问题时自动轰炸非常有用。它使我不必对每个可能失败的命令进行错误检查。

如何在函数内获得与此等效的内容?

例如,我有以下脚本,该脚本在出现错误时立即退出,并显示错误退出状态:

#!/bin/sh -e

echo "the following command could fail:"
false
echo "this is after the command that fails"

输出如预期:

the following command could fail:

现在我想将其包装到一个函数中:

#!/bin/sh -e

my_function() {
    echo "the following command could fail:"
    false
    echo "this is after the command that fails"
}

if ! my_function; then
    echo "dealing with the problem"
fi

echo "run this all the time regardless of the success of my_function"

预期输出:

the following command could fail:
dealing with the problem
run this all the time regardless of the success of my_function

实际输出:

the following output could fail:
this is after the command that fails
run this all the time regardless of the success of my_function

(即该函数忽略set -e)

这大概是预期的行为。我的问题是:如何获得效果和用处set -e在 shell 函数内?我希望能够进行一些设置,这样我就不必单独检查每个调用的错误,但脚本将在遇到错误时停止。它应该根据需要展开堆栈,直到我检查结果为止,或者如果我没有检查结果,则退出脚本本身。这是什么set -e已经这样做了,只是它不嵌套。

我发现了同样的问题 http://www.unix.com/shell-programming-scripting/114716-strange-behaviour-set-e-functions.html在 Stack Overflow 外询问,但没有合适的答案。


我最终选择了这个,这显然是有效的。我一开始尝试了导出方法,但后来发现我需要导出脚本使用的每个全局(常量)变量。

Disable set -e,然后在具有以下内容的子 shell 内运行函数调用set -e已启用。将子shell的退出状态保存在变量中,重新启用set -e,然后测试该变量。

f() { echo "a"; false;  echo "Should NOT get HERE"; }

# Don't pipe the subshell into anything or we won't be able to see its exit status
set +e ; ( set -e; f ) ; err_status=$?
set -e

## cleaner syntax which POSIX sh doesn't support.  Use bash/zsh/ksh/other fancy shells
if ((err_status)) ; then
    echo "f returned false: $err_status"
fi

## POSIX-sh features only (e.g. dash, /bin/sh)
if test "$err_status" -ne 0 ; then
    echo "f returned false: $err_status"
fi

echo "always print this"

你不能跑f作为管道的一部分,或作为&& of ||命令列表(除了作为管道或列表中的最后一个命令),或作为条件if or while,或其他忽略的上下文set -e. 此代码也不能出现在任何这些上下文中,所以如果你在函数中使用它,调用者必须使用相同的 subshel​​l / save-exit-status 技巧。这种使用set -e考虑到限制和难以阅读的语法,类似于抛出/捕获异常的语义并不真正适合一般用途。

trap err_handler_function ERR具有相同的限制set -e,因为它不会在上下文中触发错误set -e不会因命令失败而退出。

您可能认为以下内容可行,但事实并非如此:

if ! ( set -e; f );then    ##### doesn't work, f runs ignoring -e
    echo "f returned false: $?"
fi

set -e不会在子 shell 内生效,因为它记住它位于 a 的条件内if。我认为作为一个子 shell 会改变这一点,但只有在一个单独的文件中并在其上运行一个完整的单独 shell 才可以工作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 shell 函数中获得“set -e”的效果和用处? 的相关文章

  • 终端从包含空格的变量传递参数

    在终端中如何将包含空格的字符串作为参数传递 它实际上跳过了空格后面的部分 只取第一个单词 word soccer ball shell exec casperjs test js word word 那么我怎样才能转义空白它只运行这个命令
  • 使用 unix ksh shell 脚本或 perl 脚本监视文件夹中的新文件并触发 perl 脚本

    我已经在谷歌搜索和溢出了一段时间 但找不到任何可用的东西 我需要一个脚本来监视公共文件夹并在创建新文件时触发 然后将文件移动到私有位置 我有一个 samba 共享文件夹 exam ple 在 UNIX 上映射到X 在窗户上 在某些操作中 t
  • 如何输入带有空格的路径?

    我有一个主文件 它使用 从主文件我做一个源 一个带有指向路径的变量的属性文件 属性文件如下所示 TMP PATH COMPANY someProject tmp OUTPUT PATH COMPANY someProject output
  • 如何在 Linux/Unix 上根据文件类型添加文件扩展名?

    这是一个关于 Unix shell 脚本 任何 shell 的问题 但任何其他 标准 脚本语言解决方案也将受到赞赏 我有一个充满文件的目录 其中文件名是这样的哈希值 fd73d0cf8ee68073dce270cf7e770b97 fec8
  • VB6中VarType返回的vbError是什么?

    我一直在网上搜索这个 但一切都在谈论ErrObject类 或常量vbError由返回VarType功能 我想知道那个类型实际上是什么is 例如一个integer是这样的4 a string是这样的 hello world etc 对于一点背
  • Perl6:我怎样才能使所有警告都是致命的?

    我怎样才能使 Perl6 中的所有警告都是致命的 以便脚本在屏幕上出现警告时立即终止 CONTROL when CX Warn note exit 1 更频繁地死亡 该脚本终止于CONTROL when CX Warn note exit
  • 无论 Rosetta 如何,获取 M1 Mac 的真实架构

    我需要检索 Mac 的真实架构 无论该进程是否通过 Rosetta 运行 现在在 Node js 中 process arch回报x64并在外壳中 uname m回报x86 64 感谢 Ouroborus 这张纸条 https develo
  • 在多个文件中进行查找/替换的最佳方法?

    最好的方法是什么 我不是命令行战士 但我想可能有一种使用方法grep and cat 我只想替换文件夹和子文件夹中出现的字符串 最好的方法是什么 如果这很重要的话 我正在运行 ubuntu 我将为使用的人提供另一个例子ag 银色搜索者 ht
  • shell 脚本中的 Telnet

    如何在 shell 脚本中运行 telnet 并在远程服务器上执行命令 出于安全原因 我没有在我的Solaris 机器上安装expect 我也没有perlnet telnet模块已安装 那么如果不使用expect和perl我该怎么办呢 我尝
  • PHP 中是否有相当于 subprocess 的东西?

    在 Java 和 Python 中 你有ProcessBuilder or 子流程 https docs python org 2 library subprocess html可让您使用未转义字符串轻松启动进程的模块 例如 ls some
  • 如何在bash中使用kill SIGUSR2?

    我在linux中使用iptraf来监控网络流量 shell命令是 让iptraf在后台运行 iptraf s eth0 f B L traffic dat 如果我想得到结果 我必须先停止 iptraf 所以我使用 shell 命令 kill
  • Linux find 命令权限被拒绝

    我想过滤掉不必要的信息 权限被拒绝 这些是命令 的输出find type f name sources list find run lxcfs Permission denied find run sudo Permission denie
  • 如何 grep 文件中不区分大小写的字符串?

    我有一个文件file1其结尾为Success OR success 我想要grep为了这个词success以一种不区分大小写的方式 我写了以下命令 但它区分大小写 cat file1 grep success 我怎样才能改变它 以便它ret
  • Linux shell 根据第二列对文件进行排序?

    我有一个这样的文件 FirstName FamilyName Address PhoneNumber 如何按 FamilyName 排序 如果这是 UNIX sort k 2 file txt 您可以使用多个 k用于对多列进行排序的标志 例
  • 在Java中执行.lnk文件

    我需要在java中执行 lnk文件 指向exe文件的lnk文件 我能怎么做 在 VB net 中我做 Process Start path 它有效 谢谢你的帮助 Use a 流程构建器 http download oracle com ja
  • 退出代码大于 255 — 可能吗?

    如果是 在哪个操作系统 shell 或其他操作系统上 考虑以下 Java 程序 我使用 Java 只是作为示例 任何语言都适合这个问题 这更多地与操作系统有关 public class ExitCode public static void
  • 如何并行执行4个shell脚本,我不能使用GNU并行?

    我有4个shell脚本dog sh bird sh cow sh和fox sh 每个文件使用 xargs 并行执行 4 个 wget 来派生一个单独的进程 现在我希望这些脚本本身能够并行执行 由于某些我不知道的可移植性原因 我无法使用 GN
  • 当异常抛出到路由之外时,如何在 Slim 框架中传递错误页面?

    我正在尝试了解处理 Slim 框架应用程序中抛出的异常和最终页面交付的操作顺序 基本上 如果我在类中抛出异常 我希望 Slim 提供漂亮的 Twig 500 页面 但当在路由之外抛出异常时 我什至无法让 Slim 提供自己的正常错误页面 给
  • 在压缩存档内的文本文件上运行“head”,而不解压存档

    问候 我接手了之前的团队并编写了处理 csv 文件的 ETL 作业 我在 ubuntu 上结合使用 shell 脚本和 perl csv 文件很大 它们以压缩档案形式到达 解压后 很多都超过 30Gb 是的 那是 G 旧进程是在 cron
  • 捕获另一个进程未处理的异常

    我想知道我是否可以捕获我开始使用 Process Start 的另一个进程抛出的未处理的异常 我知道我可以用这个捕获标准错误link http social msdn microsoft com Forums en US csharpgen

随机推荐

  • 从 VS2015 打开 TFS 查询到 MS Excel 时出错(TF80068)

    当我们尝试使用 VS2015 中的 在 Microsoft Excel 中打开 功能在 Excel 中打开 TFS 查询结果时 我们收到错误 TF80068 Team Foundation 在与服务器通信时遇到错误 请检查您的连接并重试 E
  • ES6 带括号的箭头函数[重复]

    这个问题在这里已经有答案了 我在代码中遇到了一个小问题 这让我有点困惑 希望有人能解释为什么它会这样做 Code 1 sendText return this http get api map response Response gt re
  • 如何对使用 SimpleITK 读取的 DICOM 图像进行直方图均衡化

    我正在尝试对从 nii gz 文件读取的所有图像进行直方图均衡 我试过这段代码 import SimpleITK as sitk flair file content gdrive My Drive Colab Notebooks FLAI
  • 在ggplot2中的不同等高线图中保持相同的中断

    我正在使用 ggplot2 stat contour filled 函数创建数据不同子集的等高线图 然而 对于每种颜色 它都会产生不同的色标 这使得很难对它们进行比较 我尝试过使用 breaks 选项 但由于某种原因它不起作用 MWE 是
  • C 中的大于函数

    我知道这是一个古老的问题 您可能也遇到过这个问题 但我的解决方案中有一个错误 我不知道如何解决它 我需要编写一个比较两个整数的函数 我只允许使用操作 gt gt isGreater int x int y returns 1 if x gt
  • 将 HTML 选择元素转换为带有子菜单的树

    我想让一个选择元素有一个树形的子菜单 我希望它是这样的 source colinear com http www colinear com rmenu gif 有没有一个 jQuery 插件可以将 select 元素变成这种东西 这里有树插
  • 将 Elasticsearch 结果导出到 CSV 文件

    我正在尝试将使用以下查询找到的结果导出到桌面上的 CSV 中 这是我第一次使用 Elasticsearch 和 cURL 所以我对如何做到这一点感到困惑 from elasticsearch import Elasticsearch es
  • 在expect脚本中发送INSERT和F12

    我知道为了在期望脚本中发送返回 我会执行以下操作 send r What is the send command for the INSERT and F12 keys I ve looked online and cannot find
  • 使用Python将宏注入电子表格

    我有一个宏 我想使用一堆现有的电子表格 唯一的问题是电子表格太多了 手工做太费时间了 我已经编写了一个 Python 脚本来使用 pyWin32 访问所需的文件 但我似乎无法找到使用它来添加宏的方法 一个类似的问题here给出了这个答案 它
  • 我的用于邮寄表单的 php 脚本无法正常工作

    我正在尝试设置一个表单 将附件与电子邮件内容一起发送 但我不知道我在做什么 我对 PHP 完全陌生 刚刚学会了通过尝试和错误以及互联网上的教程来完成基本的邮件表单工作 但是 当涉及到附件时 现在我完全不知所措了 而且 尽管 PHP 脚本应该
  • Blazor 客户端 (WASM) 应用程序洞察

    Application Insights SDK 是否适用于 Blazor WASM 我正在尝试连接我的应用程序 但它不发送任何指标 即使在实例化 TelemetryClient 时 它也只是挂起 与 Blazor 服务器端不同 您不能只将
  • NSURLRequest http协议版本

    这是我今天提出的一个非常简单的问题 是否可以设置特定的HTTP协议版本NSURLRequest对象 例如 1 0 或 1 1 我在 telnet 上谈论的一个例子 pavlov pavlov telnet ya ru 80 Trying 8
  • BouncyCastle 类上的 NoClassDefFoundError

    在使用 BC 类的 Web 应用程序上一段时间后 我遇到了 NoClassDefFoundError java lang NoClassDefFoundError org bouncycastle util Pack at org boun
  • 错误:[ng:areq] 参数“MyCtrl”不是函数,未定义

    我是 Angularjs 的新手 我正在学习教程 但我在标题中遇到了错误 HTML 代码 div div div div
  • Outlook 添加、文本框、删除\退格键不起作用

    我开发了一个 Outlook 插件 自定义任务窗格 在用户控件中带有 Web 浏览器 当我在网络浏览器的文本框中写入内容时 退格键或删除按钮旁边的所有功能都运行良好 但我无法使用这些键 我是否遗漏了什么 我迟到了几年 但我设法解决了这个问题
  • 使用 SQL 语句更改忽略表添加列(如果不存在)

    我想向 mysql 表添加一个新列 但如果该列已存在 我想忽略该列的添加 我目前正在使用 ALTER IGNORE TABLE db tablename ADD COLUMN column name text NULL 但这会引发错误 ER
  • 错误:$compile:tpload 无法加载模板 Http 状态:404

    当我尝试使用 Angular 运行本地项目时 我从 Chrome 收到 404 状态 我不确定问题出在哪里 并且我已经尝试过类似问题的建议答案 这是我的指令文件 use strict ngdoc directive name stockDo
  • cmake:在 CMakeLists.txt 中选择生成器

    我想强制CMake使用 Unix Makefiles 发电机来自 CMakeLists txt 中 这是我现在使用的命令 cmake G Unix Makefiles 我希望是这样的 cmake 当在安装了 VC 和自定义工具链的 Wind
  • 在引导响应页面中如何将 div 居中

    我需要使用 bootstrap 将 div 放置在页面的中心来创建响应式页面 如下面提到的布局所示 Bootstrap 5 更新 使用弹性盒进行简单的垂直网格对齐 import url https cdnjs cloudflare com
  • 如何在 shell 函数中获得“set -e”的效果和用处?

    set e 或以 bin sh e 对于出现问题时自动轰炸非常有用 它使我不必对每个可能失败的命令进行错误检查 如何在函数内获得与此等效的内容 例如 我有以下脚本 该脚本在出现错误时立即退出 并显示错误退出状态 bin sh e echo