我有一个shell脚本,我在其中包装一个命令(mvn clean install),将输出重定向到日志文件.
#!/bin/bash
...
mvn clean install $@ | tee $logfile
echo $? # Does not show the return code of mvn clean install
Run Code Online (Sandbox Code Playgroud)
现在,如果mvn clean install失败并出现错误,我希望我的包装器shell脚本也会因该错误而失败.但是因为我将所有输出都传递给tee,所以我无法访问返回代码mvn clean install,所以当我$?之后访问时,它总是0(因为tee成功).
我尝试让命令将错误输出写入单独的文件并在之后检查,但mvn的错误输出始终为空(看起来它只写入stdout).
如何保留返回代码mvn clean install但仍然将输出传递给日志文件?
要将stdout和stderr重定向(并附加)到文件中,同时还在终端上显示它,我这样做:
command 2>&1 | tee -a file.txt
Run Code Online (Sandbox Code Playgroud)
但是,有没有其他方法可以做到这一点,以便我获得退出状态的准确值?
也就是说,如果我测试$?,我想看到退出状态command,而不是退出状态tee.
我知道我可以${PIPESTATUS[0]}在这里使用而不是$?,但我正在寻找另一种不需要检查的解决方案PIPESTATUS.
是否有一些类似的选项dash对应于外壳pipefail的bash?
或者,如果管道中的一个命令失败(但没有在其上退出,set -e那么)获得非零状态的任何其他方式.
为了更清楚,这是我想要实现的一个例子:
在调试makefile示例中,我的规则如下所示:
set -o pipefail; gcc -Wall $$f.c -o $$f 2>&1 | tee err; if [ $$? -ne 0 ]; then vim -o $$f.c err; ./$$f; fi;
Run Code Online (Sandbox Code Playgroud)
基本上它运行会在出错时打开错误文件和源文件,并在没有错误时运行程序.给我一些打字.上面的代码段运行良好,bash但我的新Ubunty系统使用dash似乎不支持pipefail选项.
如果下面一组命令的第一部分失败,我基本上想要一个FAILURE状态:
gcc -Wall $$f.c -o $$f 2>&1 | tee err
Run Code Online (Sandbox Code Playgroud)
所以我可以用它来if表达.
有没有其他方法可以实现它?
谢谢!
我试图在shell脚本中匹配字符串与正则表达式.这个字符串是脚本的参数($ 1),它是一个日期(MM/DD/YYYY)我正在尝试使用的正则表达式是:
^\d{2}[\/\-]\d{2}[\/\-]\d{4}$
Run Code Online (Sandbox Code Playgroud)
它似乎工作,我在几个正则表达式测试网站上尝试过.
我的shell代码是:
REGEX_DATE="^\d{2}[\/\-]\d{2}[\/\-]\d{4}$"
echo "$1" | grep -q $REGEX_DATE
echo $?
Run Code Online (Sandbox Code Playgroud)
"echo $?" 返回1,不管是我放入参数的字符串.
你们有个主意吗?
谢谢 !
我使用psql命令连接并在postgreSQL数据库上发出查询.任何人都可以告诉我如何检查shell脚本中执行的查询的返回状态.
我用echo $?命令来检查状态,但它总是返回零.
谢谢您的帮助.
是否有"tee"的替代方法,它捕获正在执行的命令的STDOUT/STDERR,并以与处理的命令相同的退出状态退出.如下:
eet -a some.log -- mycommand --foo --bar
Run Code Online (Sandbox Code Playgroud)
其中"eet"是"tee":)的假想替代品(-a表示追加, - 分隔捕获的命令)不应该很难破解这样的命令但是它可能已经存在并且我不知道它?
谢谢.
我正在使用命名管道来捕获另一个程序(Matlab)中的外部程序(wgrib2)的输出.Matlab代码如下所示,并system访问命令行以生成管道.这是我的问题:
myfifo使用后我是否必须关闭命名管道?代码运行后似乎仍然存在.myfifo需要关闭,关闭它的命令是什么?system('mkfifo myfifo'); % Make a named pipe myfifo
% Call the external program wgrib2 and dump its output to the named pipe myfifo
system('wgrib2.exe multi_1.glo_30m.hs.201212.grb2 -ij 1 165 -ij 1 166 > myfifo &');
fid = fopen('myfifo', 'r'); % Open the named pipe
a = fscanf(fid, '%c'); % Read the output as character
fclose(fid); % Close the "file" (myfifo still exists afterward)
Run Code Online (Sandbox Code Playgroud) 如果命令失败make,例如gcc,它退出...
gcc
gcc: fatal error: no input files
compilation terminated.
make: *** [main.o] Error 4
Run Code Online (Sandbox Code Playgroud)
但是,如果我有一个管道,则会获取管道中最后一个命令的退出状态.举个例子,gcc | cat因为cat成功不会失败.
我知道整个管道的退出代码存储在PIPESTATUS数组中,我可以得到错误代码4 ${PIPESTATUS[0]}.我应该如何构建我的makefile来处理管道命令并在正常情况下退出失败?
在评论中,另一个例子是gcc | grep something.在这里,我假设最理想的行为仍然是,gcc并且只会gcc导致失败,而不是grep如果它没有找到任何东西.
在通过另一个成功的命令传送后,如何从unix命令行应用程序中获取正确的返回码?
详细说明,情况如下:
$ tar -cEvhf - -I ${sh_tar_inputlist} | gzip -5 -c > ${sh_tar_file} -- when only the tar command fails $?=0
$ echo $?
0
Run Code Online (Sandbox Code Playgroud)
而且,我希望看到的是:
$ tar -cEvhf - -I ${sh_tar_inputlist} 2>${sh_tar_error_file} | gzip -5 -c > ${sh_tar_file}
$ echo $?
1
Run Code Online (Sandbox Code Playgroud)
有谁知道如何做到这一点?