有条件地指挥命令';s输出到bash中的/dev/null
我有以下bash脚本:有条件地指挥命令';s输出到bash中的/dev/null,bash,terminal,output-redirect,Bash,Terminal,Output Redirect,我有以下bash脚本: flag=false command_name \ $( flag == false && printf %s '>/dev/null') 我希望在终端没有输出,但我仍然得到一些。如果我将输出重定向到与命令名位于同一行的/dev/null,而不进行扩展,那么它将被抑制 命令是来自android SDK的dx工具 编辑1: 下面是脚本中的代码 dx \ --dex \ $( ( (( flag_v == 1 )) || (( f
flag=false
command_name \
$( flag == false && printf %s '>/dev/null')
我希望在终端没有输出,但我仍然得到一些。如果我将输出重定向到与命令名
位于同一行的/dev/null
,而不进行扩展,那么它将被抑制
命令是来自android SDK的dx工具
编辑1:
下面是脚本中的代码
dx \
--dex \
$( ( (( flag_v == 1 )) || (( flag_v == 'd' ))) && printf %s '--verbose') \
--no-strict \
--output="../"$app_name.jar \
$(find . -type f -name '*.class') \
$( $dexflag == false && printf %s '>/dev/null')
当我运行该工具时,它按预期工作。我不认为这可能是一个错误流。有条件地重定向Stdout
重定向是shell语法——必须在参数扩展之前的解析阶段识别重定向,因此不能通过变量扩展(不提交)生成重定向
您可以做的(在bash 4.1或更高版本中)是无条件重定向,但要更改重定向的内容:
注:
- 字符串比较以
的形式进行(或[[$var=$pattern]]
进行精确匹配)。看[[$var=“$string”]]]
- 在bash 4.1或更高版本中,
打开exec{fd_varname}>文件
,并将指向该文件的文件描述符编号放入变量文件
fd_varname
关闭编号存储在exec{fd_varname}>&-
中的文件描述符fd_varname
- 对于较旧版本的bash,您仍然可以执行此逻辑,但是您需要手动执行此操作,而不是自动分配文件描述符编号,手动分配一个未使用的FD编号,该编号不是0、1或2中的任何一个(为stdin、stdout和stderr保留)。因此,在这种情况下,
分支中的if
或exec 3>/dev/null
,在exec 3>&1
命令上的dex
和&3
exec 3>关闭它
有条件地安全生成参数列表 请参阅以进行长时间的讨论。不过,简而言之:除了重定向到
/dev/null
,还有一个简单的更改需要使其与最佳实践保持一致:使用数组
#!/bin/bash
args=( )
case $flag_v in
1|d) args+=( --verbose ) ;;
esac
while IFS= read -r -d '' filename; do
args+=( "$filename" )
done < <(find . -type f -name '*.class' -print0)
dx --dex --no-strict --output="../$app_name.jar" "${args[@]}"
#/bin/bash
args=()
案例$flag_v in
1 | d)args+=(-verbose);;
以撒
而IFS=read-r-d“”文件名;做
args+=(“$filename”)
done<有条件重定向标准输出
重定向是shell语法——必须在参数扩展之前的解析阶段识别重定向,因此不能通过变量扩展(不提交)生成重定向
您可以做的(在bash 4.1或更高版本中)是无条件重定向,但要更改重定向的内容:
注:
- 字符串比较以
[[$var=$pattern]]
的形式进行(或[[$var=“$string”]]]
进行精确匹配)。看
- 在bash 4.1或更高版本中,
exec{fd_varname}>文件
打开文件
,并将指向该文件的文件描述符编号放入变量fd_varname
exec{fd_varname}>&-
关闭编号存储在fd_varname
中的文件描述符
- 对于较旧版本的bash,您仍然可以执行此逻辑,但是您需要手动执行此操作,而不是自动分配文件描述符编号,手动分配一个未使用的FD编号,该编号不是0、1或2中的任何一个(为stdin、stdout和stderr保留)。因此,在这种情况下,
if
分支中的exec 3>/dev/null
或exec 3>&1
,在dex
命令上的&3
和exec 3>关闭它
有条件地安全生成参数列表
请参阅以进行长时间的讨论。不过,简而言之:除了重定向到/dev/null
,还有一个简单的更改需要使其与最佳实践保持一致:使用数组
#!/bin/bash
args=( )
case $flag_v in
1|d) args+=( --verbose ) ;;
esac
while IFS= read -r -d '' filename; do
args+=( "$filename" )
done < <(find . -type f -name '*.class' -print0)
dx --dex --no-strict --output="../$app_name.jar" "${args[@]}"
#/bin/bash
args=()
案例$flag_v in
1 | d)args+=(-verbose);;
以撒
而IFS=read-r-d“”文件名;做
args+=(“$filename”)
done<通过运行代码,(使用#!/bin/bash作为第一行),然后如果仍然存在问题,请使用没有语法问题的代码更新Q。另外,您知道std error
的概念吗。您还需要将该流重定向到/dev/null
。试试…>/dev/null 2>&1
(我没有否决你的Q)。祝你好运。扩展的结果,例如$()
,不会被解析为代码。因此,如果这些结果本身包含扩展,它们将不会得到尊重。这是一个特性,而不是一个bug——否则编写处理不受信任数据的shell脚本将是一场噩梦……上面假设$dexflag==false
是一个有效的语句,而事实并非如此。(如果dexflag
为空,它将作为命令运行==false
;如果true
,它将作为命令运行true==false
;由于true
命令忽略您的参数,结果将始终为真;如果$dexflag
包含false
,那么false==false
将始终为真。)返回false,因为false
命令同样根本不查看其参数)。并且(())
是算术上下文;你不能在那里进行字符串比较(如果允许的话,它会将字符串作为它们命名的变量的数值进行计算)。(请参阅标记的dupe,顺便说一句——这是一个很好的例子,说明了一个问题应该是什么样的,用尽可能简单的代码来显示问题,可以在不需要任何工具/设置的情况下运行),(使用#!/bin/bash作为第一行),然后如果您仍然有问题,请使用没有语法问题的代码更新您的Q。另外,您是否知道std error
的概念。您还需要将该流重定向到/dev/null
。尝试..>/dev/null 2>&1
(我没有对您的Q投反对票)。祝你好运。扩展的结果(如$()
)不会解析为代码。因此,如果这些结果