我需要一些帮助来调试我的 tcsh 脚本。它使用heredocs。代码:
<pre_setup> <<EOF1
<setup> <<EOF2
<command>
exit 0
EOF2
exit 0
EOF1
这<pre_setup>
是一些预设置命令(例如wash
),并且setup
是在它之后运行的一些设置。它有效,但我注意到如果setup
包含单引号,它会失败。我的设置如下:
run_setup -cmd '$SOME_ENV -o outdir'
设置run_setup
并$SOME_ENV
执行$SOME_ENV -o outdir
.所以运行:
wash -n group_name <<EOF1
run_setup -cmd '$SOME_ENV -o outdir' <<EOF2
<command>
exit 0
EOF2
exit 0
EOF1
失败SOME_ENV: Undefined variable.
。这不是wash
in的问题pre_setup
,因为如果我使用setenv X 1
(或cat
) as pre_setup
,它仍然会失败并出现相同的错误。它与heredocs 的工作方式有关。我怎样才能让它发挥作用?难道是逃跑的问题?如何调试这里文档?
我还要提到的是,run_setup -cmd '$SOME_ENV -o outdir'
在 shell 中运行是有效的。甚至跑步pre_setup
,然后这就setup
可以了。所以这与heredocs有关。
编辑:用引号括起来,像这样打破代码:
/bin/tcsh <<EOF
$WORK_AREA/script.sh.$1
echo \$status > $WORK_AREA/.$1.result
exit 0
EOF
其中 $1$ 是具有 this 的脚本的输入heredocs
。当用单引号括起来时,$1
in$WORK_AREA/script.sh.$1
为空。但如果没有引号,它就可以工作。为什么?我该如何解决?
答案1
常规的here-doc有点像双引号字符串,因为它扩展变量等:
foo=there
cat <<EOF
hello $foo
EOF
输出“你好”。在 sh-likes 中,如果未定义变量,通常不会出现错误,您只会得到一个空字符串。
请注意,引号不相关。它们在此处文档中并不特殊,就像单引号在双引号中并不特殊一样。例如,这也扩展了$foo
:echo "hello '$foo'"
看来您想阻止扩展,您可以通过引用分隔符来做到这一点。不过,类似 sh 的 shell 和 (t)csh 之间似乎有些区别。
在 sh-likes 中,这个:
foo=there
cat <<'EOF'
hello $foo
EOF
prints hello $foo
,即不尝试扩展变量。
在 (t)csh 中,您似乎需要以相同的方式引用结束分隔符,因此:
foo=there
cat <<'EOF'
hello $foo
'EOF'
<< word
读取 shell 输入直到与以下内容相同的行单词。单词不受变量、文件名或命令替换的影响,并且每个输入行都与单词在此输入行上进行任何替换之前。除非引用
\
,"
,'
或`
出现在单词[, ] 变量和命令替换在中间行上执行,允许\
引用$
,\
和`
。
我认为“最多一行相同”(和“替换前比较”)意味着引用相同。 (这与 Bash 手册页的描述不同:“如果单词被引用,分隔符是删除引号的结果单词,[...]”。)
第二部分与 POSIX sh 中的相同,带引号的分隔符会抑制此处文档文本中的扩展。
如果您从此处文档提供 shell,则您将拥有两个可以扩展任何变量的 shell。构建here-doc的外壳,然后运行内部外壳来读取它。他们可能对变量是什么有不同的想法,例如内部变量不会有主脚本的参数。引用和转义决定了其中哪一个扩展变量。
所以如果你运行这个:
#!/usr/bin/tcsh
set foo = outer
echo in outer shell, foo is: $foo
tcsh <<EOF
set foo = inner
echo "not escaped, outer shell expands: $foo"
echo " escaped: inner shell expands: \$foo"
EOF
内壳看到
set foo = inner
echo "not escaped, outer shell expands: outer"
echo " escaped: inner shell expands: $foo"
第一个$foo
已经展开,并且反斜杠从\$foo
.如果你用它<<'EOF'
代替,外壳不会膨胀。
因此,在这里,您需要使用<<EOF
不带引号的内容,并根据您想要发生的情况,注意单独转义或不转义所有变量。