- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
下面是我正在编写的脚本的简化方案。程序必须以不同的方式获取参数,因此对几个函数进行了精细划分。
问题是从深层函数返回值的链式加载在陷阱处中断,在陷阱处检查结果以显示消息。
#! /usr/bin/env bash
check_a_param() {
[ "$1" = return_ok ] && return 0 || return 3
}
check_params() {
# This trap should catch negative results from the functions
# performing actual checks, like check_a_param() below.
return_trap() {
local retval=$?
[ $retval -ne 0 ] && echo 'Bad, bad… Dropping to manual setup.'
return $retval
}
# check_params can be called from different functions, not only
# setup(). But the other functions don’t care about the return value
# of check_params().
[ "${FUNCNAME[1]}" = setup ] \
&& trap "return_trap; got_retval=$?; trap - RETURN; return $got_retval;" RETURN
check_a_param 'return_bad' || return $?
# …
# Here we check another parameters in the same way.
# …
echo 'Provided parameters are valid.'
return 0 # To be sure.
}
ask_for_params() {
echo 'User sets params manually step by step.'
}
setup() {
[ "$1" = force_manual ] && local MANUAL=t
# If gathered parameters do not pass check_params()
# the script shall resort to asking user for entering them.
[ ! -v MANUAL ] && {
check_params \
&& echo "check_params() returned with 0. Not running manual setup."
|| false
}|| ask_for_params
# do_the_job
}
setup "$@" # Either empty or ‘force_manual’.
它应该如何工作:
↗ 3 → 3→ trap →3 ↗ || ask_for_params ↘
check_a_param >>> check_params >>> [ ! -v MANUAL ] ↓
↘ 0 → 0→ trap →0 ↘ && ____________ do_the_job
想法是,如果检查失败,它的返回码强制check_params()
也返回,这反过来又会触发 || ask_for_params
条件 setup()
.但是陷阱返回 0:
↗ 3 → 3→ trap →0
check_a_param >>> check_params >>> [ ! -v MANUAL ] &&… >>> do_the_job
↘ 0 → 0→ trap →0
如果您尝试按原样运行脚本,您应该会看到
Bad, bad… Dropping to manual setup.
check_params() returned with 0. Not running manual setup.
这意味着错误的结果触发了陷阱(!)但是设置它的母函数没有传递结果。
试图设置一个 hack 我已经尝试过
declare -g retval=$?
在return_trap()
并在设置陷阱的行中使用它的值。变量已设置([ -v retval ]
成功返回),但是……没有值。有趣。retval=Eeh
到 check_params()
, 在 return_trap()
之外并将其设置为 $?
作为通常的参数。不,retval
在函数中没有设置全局变量的值,它保持为“Eeh”。不,没有 local
指示。默认情况下,它应该被视为全局的。如果你把 test=1
至 check_params()
和 test=3
在 check_a_param()
然后用 echo $test
打印出来在 setup()
的末尾,你应该看到 3。至少我看到了。 declare -g
正如预期的那样,这里没有任何区别。return_trap()
连同 declare -g retval=Eeh
没有任何区别。当现代软件走向衰落时,是时候诉诸于旧的写入文件的方式了。让我们使用 retval=$?; echo $retval >/tmp/t
将 retval 打印到/tmp/t在 return_trap()
并用
trap "return_trap; trap - RETURN; return $(</tmp/t)" RETURN
现在我们终于可以看到最后一个从文件中读取数字的 return 指令实际上返回了 3。但是 check_params()
仍然返回 0!
++ trap - RETURN
++ return 3
+ retval2=0
+ echo 'check_params() returned with 0. Not running manual setup.'
check_params() returned with 0. Not running manual setup.
如果参数为 trap
command 严格来说是一个函数名,它返回原始结果。原来一个,不是什么return_trap()
返回。我试图增加结果,但仍然得到 3。您可能还会问“为什么您需要如此频繁地解除陷阱?”。这是为了避免另一个错误,该错误导致陷阱每次都触发,即使是 check_params()
时也是如此。从另一个函数调用。 RETURN 上的陷阱是本地事物,它们不会被其他函数继承,除非在它们上明确设置了调试或跟踪标志,但看起来它们在运行之间保留了陷阱设置。或者 bash 为他们设置陷阱。仅当从特定函数调用 check_params() 时才应设置此陷阱,但如果未取消设置陷阱,则每次都会继续触发 check_a_param()
返回一个大于零的值,与 FUNCNAME[1]
中的内容无关.
在这里我放弃了,因为我现在看到的唯一导出是在每个|| return $?
之前对调用函数实现检查。在 check_params()
.但它太丑了,伤了我的眼睛。
我只能补充一点,$?
在设置陷阱的行中,将始终返回 0。 因此,例如,如果您声明一个 local
变量 retval
在 return_trap()
, 并放入这样的代码来检查它
trap "return_trap; [ -v retval ]; echo $?; trap - RETURN; return $retval" RETURN
无论retval
是否存在,它都会打印 0实际上是设置还是不设置,但是如果你使用
trap "return_trap; [ -v retval ] && echo set || echo unset; trap - RETURN; return $retval" RETURN
它将打印‘unset’。
GNU bash,版本 4.3.39(1)-release (x86_64-pc-linux-gnu)
最佳答案
很有趣,
trap "return_trap; trap - RETURN" RETURN
简单有效。
[ ! -v MANUAL ] && {
check_params; retval2=$?
[ $retval2 -eq 0 ] \
&& echo "check_params() returned with 0. Not running manual setup." \
|| false
}|| ask_for_params
这是踪迹。
+ check_a_parameter return_bad
+ '[' return_bad = return_ok ']'
+ return 3
+ return 3
++ return_trap
++ local retval=3
++ echo 3
++ '[' 3 -ne 0 ']'
++ echo 'Bad, bad… Dropping to manual setup.'
Bad, bad… Dropping to manual setup.
++ return 3
++ trap - RETURN
+ retval2=3
+ '[' 3 -eq 0 ']'
+ false
+ ask_for_params
+ echo 'User sets params manually step by step.'
User sets params manually step by step.
所以答案很简单:不要尝试覆盖传递给 trap
命令的行中的结果。 Bash 为您处理一切。
关于linux - 如何使 bash 中的 RETURN 陷阱保留返回码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36442572/
正如问题所说,C++ 程序员在转向 Java 时面临哪些常见/主要问题?我正在寻找一些广泛的主题名称或示例以及工程师必须进行的日常调整。然后我可以去深入阅读这个。 我对多年来使用 C++ 并不得不使用
我们正在准备发布一个在过去一年中一直在开发的大型网络应用程序。我们即将开始集成 ActiveMerchant 的过程,以处理该服务的经常性订阅费用。 我正在寻找关于考虑到我们的要求(如下所列)的最佳实
您陷入过哪些 Powershell 陷阱? :-) 我的是: # ----------------------------------- function foo() { @("text")
对于商业数据库而言,数据库升级是一个优先级很高的事情,有版本升级路线图,有相应的补丁,而且对于方案还有一系列的演练,显然是一场硬仗。而在MySQL方向上,升级这件事情就被淡化了许多,好像只能证明它的
Android 新增了 AsyncLayoutInflater类到他们的支持库版本 24.0 和更高版本,并且可以在 Android SDK 4.0 或更高版本(几乎所有可用的设备)中使用。 根据 A
作为一名刚接触 Vala 的程序员,您对刚接触该语言的人的第一条建议是什么? 最佳答案 这很大程度上取决于您的背景。如果您来自 C/C++/Java,最好的建议是学习函数式编程。 Vala 支持真正的
作为 Spring 世界的新手,我认为如果有一个社区 Wiki 页面列出基于 Spring 的项目中常见的陷阱会很好。 这些包括: 被误解的概念 在 Spring 3.X 中不再推荐的 Spring
我正在开发一个脚本来管理一些陷阱。一开始我只用这段代码管理 INT 和 SIGTSTP,它工作得很好: #!/bin/bash function capture_traps() { echo
bash 中是否可以在函数退出时调用某些命令。我的意思是: function foo { # something like this maybe? trap "echo \"exit
我们在我们的域中托管了一个应用程序。所有用户都需要先通过 POST 表单登录。登录后,表单会自动重定向到我们网站上的仪表板页面。 是否可以允许一些客户托管他们自己的登录表单(在他们的网站上),然后发布
我有一个无窗口计时器(没有 WM_TIMER),它只在给定的时间段过去后触发一次回调函数。它作为 SetTimer()/KillTimer() 实现。时间段足够小:100-300 毫秒。 对于每个如此
我使用 Java 大约一个月了,总体而言仍然是编程方面的业余爱好者,所以如果我有什么不对的地方,请随时纠正我。也许我会提供一些多余的细节,但我现在很困惑,无法决定什么才是重要的。 因此,我一直在开发多
我正在开发一个需要使用 FileSystemWatcher 类的 C# 程序,以便在创建新文件时通知它。作为初始化的一部分,程序会扫描目录,以便处理其中已存在的任何文件。一切正常。 但是,在与另一位开
下面材料整理自Internet&著作。 STL中的容器按存储方式分为两类,一类是按以数组形式存储的容器(如:vector 、deque);另一类是以不连续的节点形式存储的容器(如:list
我正在使用 NuGet 包 Polly实现捕获故障转移 SQL 异常的重试逻辑。我在 Azure 中设置了 SQL Server Always On 高可用性。 我不想捕获所有 SQL 异常(这是不正
在编写 Scala RemoteActor 代码时,我注意到了一些陷阱: 必须设置 RemoteActor.classLoader = getClass().getClassLoader() 以避免“
出于某种原因,当我针对不存在的文件运行以下脚本时,我的脚本没有捕获异常。我基于我在网上找到的示例中的代码,但它似乎对我不起作用。 我将不胜感激有关如何解决此问题的任何提示或指示。 注意:在下面的例子中
我正在尝试从 R 调用 winBUGS 来估计逻辑回归。我正在使用以下代码: # Directorio de trabajo setwd("~/3 Diplomado/7 Bayesiana/8t1"
我正在尝试从 R 调用 winBUGS 来估计逻辑回归。我正在使用以下代码: # Directorio de trabajo setwd("~/3 Diplomado/7 Bayesiana/8t1"
我正在使用 ctypes 包装一个大型 C 库。 ctypesgen生成了包装代码(与我自己的做法相差不远)。作为包装 C 结构的 ctypes 的一部分,它们被制作为对象,其中一些在 C 中具有“s
我是一名优秀的程序员,十分优秀!