我在将一些带有空格的字符串变量作为参数传递给程序时遇到困难。
为了调试和显示正在传递的参数,我创建了一个演示 Python 脚本 -:
##### show_args.py #####
import sys
def main():
# Display the arguments passed to the script
print "Number of arguments =", len(sys.argv)
for arg in sys.argv:
print arg
if __name__ == '__main__':
main()
现在,演示该问题的脚本 -:
path_with_spaces="$HOME/blah blah"
arg_list="$path_with_spaces/abc $path_with_spaces/xyz"
python show_args.py $arg_list
输出 -:
Number of arguments = 5
show_args.py
/home/anmol/blah
blah/abc
/home/anmol/blah
blah/xyz
我真正想要的是这样的——:
path_with_spaces="$HOME/blah blah"
python show_args.py "$path_with_spaces/abc" "$path_with_spaces/xyz"
输出 -:
Number of arguments = 3
show_args.py
/home/anmol/blah blah/abc
/home/anmol/blah blah/xyz
为了确认问题仅发生在带有空格的路径上,我创建了以下脚本 -:
path_without_spaces="$HOME/blah"
arg_list="$path_without_spaces/abc $path_without_spaces/xyz"
python show_args.py $arg_list
输出 -:
Number of arguments = 3
show_args.py
/home/anmol/blah/abc
/home/anmol/blah/xyz
在寻找这个问题的解决方案时,我遇到了这个答案,根据该方法,正确的方法是将参数放入数组变量而不是字符串变量中。
显示这种新方法的脚本 -:
path_with_spaces="$HOME/blah blah"
arg_list=("$path_with_spaces/abc" "$path_with_spaces/xyz")
python show_args.py "${arg_list[@]}"
输出 -:
Number of arguments = 3
show_args.py
/home/anmol/blah blah/abc
/home/anmol/blah blah/xyz
虽然这个解决方案工作正常,我仍然想知道是否有一种方法可以使用字符串变量而不是数组变量来完成同样的事情。
我的系统配置-:
- Ubuntu 14.04 LTS
- 重击 4.3.11
- 侏儒终端 3.6.2
答案1
在:
path_with_spaces="$HOME/blah blah"
arg_list="$path_with_spaces/abc $path_with_spaces/xyz"
python show_args.py $arg_list
您正在使用标量/字符串变量并使用分割+全局运算符(将该变量不加引号)分割该变量的内容并生成要传递给 的参数python
。
这分裂的一部分分割+全局运算符对存储在特殊参数中的字符进行拆分$IFS
。
在这里,您可以禁用全局部分并分割在您的路径中找不到的角色上。例如,如果新队在路径中找不到:
path_with_spaces="$HOME/blah blah"
arg_list="$path_with_spaces/abc
$path_with_spaces/xyz"
IFS="
"
set -f # disable glob.
python show_args.py $arg_list
您还可以使用 shell 引用并使用eval
shell 解释这些引号(此处使用bash
特定功能):
printf -v arg_list '%q ' "$path_with_spaces/abc" \
"$path_with_spaces/xyz"
eval "python show_args.py $arg_list"
答案2
是的。
您可以使用默认的路径分隔符来分隔路径。路径名中有两种非法字符:
人物
\0NUL
路径
/
分隔符
碰巧,您可以将分隔符上的路径名与 shell 的内部字段分隔符 $IFS
特殊参数。当两个或多个分隔符依次出现时,生成的组件将是一个\0NUL
有价值的参数 - 不能是路径名。
要工作,您必须直接 root 所有路径(因此排除根//
),并且您必须确保拥有规范路径 - 或者至少所有路径//*
都被压缩到每个路径中出现一次(点不会伤害 - 或帮助)。一旦你这样做了:
paths='/path/one//path/t w o//p a t h/t h r e e/'
set -f --; IFS=/
for p in ${paths#/}$IFS
do printf ${p:+/}%s\\n "$*"
set -- ${p:+"$@"/$p}
done
/path/one
/path/t w o
/p a t h/t h r e e
$PWD
您可以在w/中获得规范路径cd
。
cd -- /some//../screwy/../path/to///destination
printf %s\\n "$PWD"
/path/to/destination
如果使用该-P
开关,cd
将确保当前工作目录的绝对物理路径设置为$PWD
. Else with-L
或 by defaultcd
将在 shell 会话进行时保留先前对符号链接目录所做的更改所隐含的任何间接。
因此,您可以通过遍历树来最可靠地收集树中的名称。