如何在 zsh 中引用文件名中的字符串(传回其他脚本)

dai*_*len 5 zsh

我有一个脚本,文件名中有一个字符串,如下所示:

filename_with_spaces="a file with spaces"
echo test > "$filename_with_spaces"
test_expect_success "test1: filename with spaces" "
  run cat \"$filename_with_spaces\"
  run grep test \"$filename_with_spaces\"
"
Run Code Online (Sandbox Code Playgroud)

test_expect_success定义为:

test_expect_success () {
  echo "expecting success: $1"
  eval "$2"
}
Run Code Online (Sandbox Code Playgroud)

run定义为:

#!/bin/zsh
# make nice filename removing special characters, replace space with _
filename=`echo $@ | tr ' ' _ | tr -cd 'a-zA-Z0-9_.'`.run
echo "#!/bin/zsh" > $filename
print "$@" >> $filename
chmod +x $filename
./$filename
Run Code Online (Sandbox Code Playgroud)

但是当我运行顶级脚本时test_expect_success......我得到cat_a_file_with_spaces.run

#!/bin/zsh
cat a file with spaces
Run Code Online (Sandbox Code Playgroud)

a file with spaces问题是in周围的引号cat_a_file_with_spaces.run丢失了。如何让 Z shell 保持正确的引用?

谢谢

ZyX*_*ZyX 6

尝试

run cat ${(q)filename_with_spaces}
Run Code Online (Sandbox Code Playgroud)

。这就是 (q) 修饰符的编写目的。运行脚本相同:

echo -E ${(q)@} >> $filename
Run Code Online (Sandbox Code Playgroud)

。而且它不是 bash,你不需要在变量周围加上引号:除非你指定了一些选项(不记得到底是哪个)

command $var
Run Code Online (Sandbox Code Playgroud)

command无论 中是什么,总是只传递一个参数$var。为了确保某些 zsh 选项不会改变行为,请输入

emulate -L zsh
Run Code Online (Sandbox Code Playgroud)

在每个脚本的顶部。

请注意,初始变体 ( run cat \"$filename_with_spaces\") 不是正确的引用:文件名可以包含除 NULL 之外的任何字符,并/用于分隔目录。${(q)}关心它。

更新:我会按以下方式编写 test_expect_success 函数:

function test_expect_success()
{
    emulate -L zsh
    echo "Expecting success: $1" ; shift
    $@
}
Run Code Online (Sandbox Code Playgroud)

用法:

test_expect_success "Message" run cat $filename_with_spaces
Run Code Online (Sandbox Code Playgroud)

  • @Slothman 明白了。`echo` 和 `print` 正在删除额外级别的反斜杠。不要使用`print ${(qq)@}`,使用`echo -E ${(q)@}`。 (2认同)