如何在 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”的效果和用处? 的相关文章

  • 由于 AndroidManifest.xml 问题,无法构建 APK

    For some reason whenever I load my project I immediately get the following error 我的代码中AndroidManifest xml
  • 在 shell 中将 ANSI 转换为 UTF-8

    我正在制作一个解析器 1 csv 到 3 csv 脚本 但遇到问题 我是法国人 所以用我的语言我有这样的字母 一位客户向我发送了一个 csv 文件 Linux 将其识别为 unknown 8bit 我猜是 ansi 在我的脚本中 我正在编写
  • 创建 QT 应用程序作为 Windows 上现有基于控制台的应用程序的 GUI

    我正在尝试使用 Qt 为现有应用程序设置一个 GUI 该应用程序旨在在 Windows 命令行中运行 这不仅仅是运行应用程序system 命令 但我需要通过命令行与现有应用程序交互 The system 当我启动现有的可执行文件时 命令会阻
  • 如何实现一个“更好”的Finally Rx操作符?

    最近我意识到 RxFinally https learn microsoft com en us previous versions dotnet reactive extensions hh212133 v vs 103 操作符的行为方式
  • 如何使用AWK从文件中连续输出行

    我有一个多行文件 我想连续输出文件的某些行 比如第一次 从第1行打印到第5行 下次 打印第2行到第6行 依此类推 我发现 AWK 是一个非常有用的函数 我尝试自己编写代码 但它什么也没输出 以下是我的代码 bin bash for n in
  • 运行 php 脚本的 Bash 脚本

    我有一个 php 脚本 我想使用 bash 脚本运行它 所以我可以使用 Cron 每分钟左右运行 php 脚本 据我所知 我需要创建 bash 脚本来处理 php 脚本 然后我才能使用 Cron 工具 计时器 到目前为止 我被告知我需要输入
  • 有没有办法获取正在运行或新打开的资源管理器窗口的 IExplorerBrowser 接口以供后续 BrowseToXXX 调用?

    这么问是因为在上一个问题 https stackoverflow com questions 6220899 answer 6221898我是指向 IExplorerBrowser 的指针 但是它创建了一个子窗口 而我想模拟资源管理器的 查
  • 警告:implode() [function.implode]:传递的参数无效

    我收到以下错误 警告 implode function implode 在第 1335 行的 wp content themes mytheme functions php 中传递的参数无效 at function my get tags
  • 离开页面时 JQuery Ajax 错误

    我使用以下代码将数据从服务器异步提取到客户端 错误块中的警报报告服务器上发生的错误 但是 如果用户在调用过程中离开页面 该块也会被触发并抛出一个空的警报容器 有什么方法可以更优雅地处理用户离开页面的情况 即在离开之前不抛出空警报 也许可以通
  • 我可以在远程服务器上运行位于本地计算机上的 bash 脚本吗?

    我有本地脚本 我想在远程服务器上运行 我已经设置了 ssh 密钥对以启用无需密码的登录 我当前的方法是将脚本 rsync 到服务器 然后运行它 ssh user remoteserver rsync localserver script s
  • 何时捕获 java.lang.Error?

    在什么情况下应该抓住java lang Error在申请上 一般来说 永远不会 但是 有时您需要捕获特定的错误 如果您正在编写类似框架的代码 加载第 3 方类 那么最好抓住LinkageError 未找到类定义 链接不满足 类更改不兼容 我
  • 如何在 linux bash shell 中对字符串数组进行排序? [复制]

    这个问题在这里已经有答案了 例如 数组是 link2 pathname link1 pathname link3 pathname 我怎样才能得到像下面这样的数组 link1 pathname link2 pathname link3 pa
  • If 语句不遵循其条件

    在我的滚动代码中 您只需编写 r 然后按 Enter 键 但似乎不会读取该内容并转到重新启动 while 循环的 else 让它滚动的唯一方法是输入除 r 之外的其他内容 而不是 standard in 1 解析错误 bin bash th
  • bash:从数组中删除变量? [复制]

    这个问题在这里已经有答案了 bin bash tank one two three x two unset tank x echo tank 我想从数组中删除 x 但不知何故它删除了数组的第一个元素 我该如何解决这个问题 您有一个索引数组
  • 如何在 ruby​​ 中后台运行多个外部命令

    给定这个 Unix shell 脚本 test sh bin sh sleep 2 sleep 5 sleep 1 wait 时间 test sh real 0m5 008s user 0m0 040s sys 0m0 000s 如何在 U
  • unix 命令行执行方式为 . (点)与没有

    在 unix 命令行中 通过简单地键入程序名称来执行程序与通过键入 点 后跟程序名称 例如 runme vs runme name来源称为文件name进入当前外壳 所以如果一个文件包含这个 A hello 然后 如果您获取它 之后您可以引用
  • 如何通过管道将输入和输出传送到交互式 shell?

    我正在尝试构建一个应用程序 使用户能够与命令行交互式 shell 例如 IRB 或 Python 进行交互 这意味着我需要将用户输入通过管道传输到 shell 并将 shell 的输出返回给用户 我希望这会像管道 STDIN STDOUT
  • 在大型文本文件中查找重复记录

    我在一台 Linux 机器 Redhat 上 并且有一个 11GB 的文本文件 文本文件中的每一行包含单个记录的数据 并且该行的前 n 个字符包含该记录的唯一标识符 该文件包含略多于 2700 万条记录 我需要验证文件中不存在具有相同唯一标
  • 从命令行获取设备的 Android SDK 版本

    我计划构建一个自动化系统 用于将 Android 版本部署到各种设备 以便使多平台开发更加轻松 有没有办法通过android shell或adb获取连接设备的sdk版本 将有一台计算机连接多个测试设备 我计划编写一个脚本 该脚本将从构建服务
  • 在 F# 中“合并”受歧视的联合?

    继从这个问题 https stackoverflow com questions 53506325 result vs raise in f async 我在组合不同类型时遇到问题Result类型在一起 以下是一个人为的示例 不是真实的代码

随机推荐

  • 从 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