Bash-字符串、命令和转义(哦,天哪!)

Bash-字符串、命令和转义(哦,天哪!),bash,shell,Bash,Shell,我现在正在浪费这么多的时间试图弄明白这么简单的事情 伪代码(几种语法的混合,抱歉): 这是有效的 FIND=$(find $LOG_DIR -type f | grep -v -f $EXCLUDE | nl -ba -s' ') printf "%s\n" "$FIND" 这不 NL="nl -ba -s' '" FIND=$(find $LOG_DIR -type f -mtime +$ARCH_AGE | grep -v -f $EXCLUDE | $NL) printf "

我现在正在浪费这么多的时间试图弄明白这么简单的事情

伪代码(几种语法的混合,抱歉):


这是有效的

FIND=$(find $LOG_DIR -type f | grep -v -f $EXCLUDE | nl -ba -s'   ')

printf "%s\n" "$FIND"
这不

NL="nl -ba -s'  '"
FIND=$(find $LOG_DIR -type f -mtime +$ARCH_AGE | grep -v -f $EXCLUDE | $NL)

printf "%s\n" "$FIND"
这也不是

NL='nl -ba -s'\''   '\'' '
不过,这确实有效:

find /my/starting/path -type f | grep -v -f /my/exclude/files |  nl -ba -s'  ' 


缩写:展开
$foo
unquoted通过字符串拆分和全局展开运行内容,但语法解析。这意味着在不同上下文中进行引用和转义的字符不被视为语法,而只被视为数据


如果您想通过语法分析来运行字符串,请使用
eval
——但请注意警告,这些警告非常大,并且会影响安全性

更好的方法是使用合适的工具来完成这项工作——在shell数组中构建单个简单命令(而不是管道!),并使用函数作为构建复杂命令的可组合单元。描述了这些工具,并深入讨论了它们中的哪一个在什么时候合适


要更具体一些,请执行以下操作:

nl=( nl -ba -s'  ' )
find_output=$(find "$log_dir" -type f -mtime "+$arch_age" | grep -v -f "$exclude" | "${nl[@]}")
printf "%s\n" "$find_output"

…将是正确的,因为它将简单命令
nl
作为数组进行跟踪。

缩写:Expanding
$foo
unquoted通过字符串拆分和全局展开运行内容,但不进行语法解析。这意味着在不同上下文中进行引用和转义的字符不被视为语法,而只被视为数据


如果您想通过语法分析来运行字符串,请使用
eval
——但请注意警告,这些警告非常大,并且会影响安全性

更好的方法是使用合适的工具来完成这项工作——在shell数组中构建单个简单命令(而不是管道!),并使用函数作为构建复杂命令的可组合单元。描述了这些工具,并深入讨论了它们中的哪一个在什么时候合适


要更具体一些,请执行以下操作:

nl=( nl -ba -s'  ' )
find_output=$(find "$log_dir" -type f -mtime "+$arch_age" | grep -v -f "$exclude" | "${nl[@]}")
printf "%s\n" "$find_output"

…将是正确的,因为它将简单命令
nl
作为数组进行跟踪。

缩写:Expanding
$foo
unquoted通过字符串拆分和全局展开运行内容,但不进行语法解析。这意味着在不同上下文中进行引用和转义的字符不被视为语法,而只被视为数据


如果您想通过语法分析来运行字符串,请使用
eval
——但请注意警告,这些警告非常大,并且会影响安全性

更好的方法是使用合适的工具来完成这项工作——在shell数组中构建单个简单命令(而不是管道!),并使用函数作为构建复杂命令的可组合单元。描述了这些工具,并深入讨论了它们中的哪一个在什么时候合适


要更具体一些,请执行以下操作:

nl=( nl -ba -s'  ' )
find_output=$(find "$log_dir" -type f -mtime "+$arch_age" | grep -v -f "$exclude" | "${nl[@]}")
printf "%s\n" "$find_output"

…将是正确的,因为它将简单命令
nl
作为数组进行跟踪。

缩写:Expanding
$foo
unquoted通过字符串拆分和全局展开运行内容,但不进行语法解析。这意味着在不同上下文中进行引用和转义的字符不被视为语法,而只被视为数据


如果您想通过语法分析来运行字符串,请使用
eval
——但请注意警告,这些警告非常大,并且会影响安全性

更好的方法是使用合适的工具来完成这项工作——在shell数组中构建单个简单命令(而不是管道!),并使用函数作为构建复杂命令的可组合单元。描述了这些工具,并深入讨论了它们中的哪一个在什么时候合适


要更具体一些,请执行以下操作:

nl=( nl -ba -s'  ' )
find_output=$(find "$log_dir" -type f -mtime "+$arch_age" | grep -v -f "$exclude" | "${nl[@]}")
printf "%s\n" "$find_output"

…这是正确的,因为它将简单命令
nl
作为一个数组进行跟踪。

BashFAQ#50相当全面地介绍了这个主题:omg。。。我想我会找到答案的。就在我发布问题的时候。这种情况经常发生。总是。听起来像是
eval
的工作。顺便说一句——按照惯例,所有大写名称都是为环境变量和shell内置名保留的。为了避免错误地覆盖这些变量,未导出到环境中的shell变量的名称中应至少包含一个小写字符(并且所有小写名称都是通用的).所有大写变量名在代码中都很常见,这些代码都是由见过环境变量和内置代码的人编写的,他们假设所有变量在shell中都是这样工作的。可悲的是,学习shell通常是通过示例进行的,而示例往往很糟糕……BashFAQ#50相当全面地介绍了这个主题:天哪。。。我想我会找到答案的。就在我发布问题的时候。这种情况经常发生。总是。听起来像是
eval
的工作。顺便说一句——按照惯例,所有大写名称都是为环境变量和shell内置名保留的。为了避免错误地覆盖这些变量,未导出到环境中的shell变量的名称中应至少包含一个小写字符(并且所有小写名称都是通用的).所有大写变量名在代码中都很常见,这些代码都是由见过环境变量和内置代码的人编写的,他们假设所有变量在shell中都是这样工作的。可悲的是,学习shell通常是通过示例进行的,而示例往往很糟糕……BashFAQ#50相当全面地介绍了这个主题:天哪。。。我想我会找到答案的。就在我发布问题的时候。这种情况经常发生。总是。听起来像是
eval
的工作。顺便说一句——按照惯例,所有大写名称都是为环境变量和shell内置名保留的。为了避免错误地覆盖这些变量,未导出到环境中的shell变量的名称中应至少包含一个小写字符(所有小写名称都是通用的)。所有大写变量名称在看过环境变量和生成环境变量的人员编写的代码中都是通用的