我正在使用KSH
脚本来执行具有以下语法的二进制(程序)来正确执行:
myprog [-v | --verbose (optional)] [input1] [input2]
程序没有打印任何内容成功时返回退出代码0(零)。失败时,它会将ERROR消息打印到STDERR
&返回exit status > 0
。如果指定了-v
选项,则会在成功和失败的情况下将详细信息打印到STDOUT
。
为了使这个可用并减少参数交换和用户控制日志记录的机会,我使用了一个ksh shell脚本来调用这个二进制文件。运行ksh shell脚本的语法如下:
如果指定了-v
选项,则ksh会将STDOUT
重定向到<execution_date_time>_out.log
,将STDERR
重定向到<execution_date_time>_err.log
。我的ksh脚本如下:
myshell.sh:
#! /bun/ksh
verbopt=""
log=""
arg1=""
arg2=""
dateTime=`date +%y-%m-%d_%H:%M:%S`
while getopts "va:b:" arg
do
case $arg in
v) # verbose output
verbopt="-v"
log="1>${dateTime}_out.log 2>${dateTime}_err.log"
;;
a) # Input 1
arg1=$OPTARG
;;
b) # Input 2
arg2=$OPTARG
;;
*) # usage
echo "USAGE: myshell.sh [-v] [-a input1] [-b input2]"
exit 2
;;
esac
done
if [[ -z $arg1|| -z $arg2]]
then
echo "Missing arguments"
exit 2
fi
myprog $verbopt $arg1 $arg2 $log
exit $?
这里的问题是,所有输出STDERR
&amp;在屏幕上打印STDOUT
(即,没有发生重定向)以及在执行成功或不成功后没有创建*.log
个文件(即退出状态:分别为0或> 0)。 / p>
任何人都可以帮我解决这个问题吗? 感谢。
答案 0 :(得分:2)
而不是尝试将补丁重定向到命令行,只需在解析标志时重定向流。那就是:
while getopts "va:b:" arg
do
case $arg in
v) # verbose output
verbopt="-v"
exec 1>${dateTime}_out.log 2>${dateTime}_err.log
;;
...
你需要小心一点,因为你在此之后做了一些错误检查,你可能不希望你以后的错误消息转到* _err.log,但这很难解决。 (例如,错误检查更快,或在错误检查后执行test -n "$verbopt" && exec > ...
或类似)
答案 1 :(得分:1)
问题是>
的价值未扩展$log
。
我担心你需要使用条件,例如:
cmd="myprog $verbopt $arg1 $arg2"
if [ "$log" ]; then
$cmd 1>${dateTime}_out.log 2>${dateTime}_err.log
else
$cmd
fi
答案 2 :(得分:0)
我会使用成语exec
重定向,它运行脚本的其余部分,就好像在运行时提供了给定的重定向一样:
if need_to_log; then
exec >stdout_file 2>stderr_file
fi
this command will be logged if the above if statement was true
如果您需要在以后恢复stdout和stderr以使脚本执行更多未记录的事情,则可以在子shell中运行日志记录部分:
(
if need_to_log; then
exec >stdout_file 2>stderr_file
fi
this command will be logged if the above if statement was true
)
this command will not be logged regardless
我还会在数组中构建命令,因此您可以向其添加-v
之类的内容,而无需为每个可能的参数添加单独的变量。如果将-a
和-b
参数提供给myprog
的顺序并不重要,您可以将它们添加到数组中,而不是使用单独的变量。
您可以在下面看到我的版本。除了上述更改之外,如果没有记录,我也不会在没有记录的情况下获取时间戳,因为它不需要,并且使用ksh builtin print
将错误消息发送到标准错误而不是标准输出。 / p>
以下是我放在一起的内容:
#!/usr/bin/env ksh
# new array syntax requires ksh93+; for older ksh, use this:
# set -A cmd myprog
cmd=(myprog) # build up the command to run in an array
log_flag=0 # nonzero if the command should be logged
input_a= # the two input filenames
input_b=
while getopts 'va:b:' arg; do
case $arg in
v) # verbose output
# older ksh: set -A cmd "${cmd[@]}" -v
cmd+=(-v)
log_flag=1
;;
a) # Input 1
input_a=$OPTARG
;;
b) # Input 2
input_b=$OPTARG
;;
*) # usage
print -u2 "USAGE: $0 [-v] [-a input1] [-b input2]"
exit 2
;;
esac
done
if [[ -z $input_a || -z $input_b ]]; then
print -u2 "$0: Missing arguments"
exit 2
fi
if (( log_flag )); then
timestamp=$(date +%y-%m-%d_%H:%M:%S)
exec >"${timestamp}_out.log" 2>"${timestamp}_err.log"
fi
"${cmd[@]}" "$input_a" "$input_b"
您的时间戳使用两位数年份(%y
);这些和组件之间的下划线是唯一与ISO 8601标准的偏差,因此我建议您继续采用标准格式。这应该是%Y-%m-%dT%H:%M:%S
,或者在包含较新版本的strftime
,%FT%T
的C库中。
您也可以更聪明一点,让log_flag
为空或-q
的字符串,将其传递给命令,并针对空字符串进行测试以确定是否为打开日志文件,但我发现逻辑更容易理解,简单的0/1值被视为布尔值。
答案 3 :(得分:-1)
查看QueryException
Error Code : 904
Error Message : ORA-00904: "FIRSTNAME": invalid identifier
Position : 69
命令。
替换......
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,new String[]{ Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS }, 12345);
} else {
// WE ALREADY HAVE PERMISSION, RUN THE MAIN FUNCTION
shoro();
}
}
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
Toast.makeText(this,"salam1",Toast.LENGTH_SHORT).show();
if ((requestCode == 12345) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
Toast.makeText(this,"salam2",Toast.LENGTH_SHORT).show();
// WE GOT THE PERMISSION, RUN THE MAIN FUNCTION
try {
shoro();
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用:
eval
我不知道你的myprog $verbopt $arg1 $arg2 $log
做了什么,但这是一个使用eval myprog $verbopt $arg1 $arg2 $log
来运行myprog
(有效命令)和eval
(无效命令)的简单示例,重定向因此输出到log.stdout / log.stderr:
date
现在运行脚本:
date xyz