如何在CSH中存储变量或回显时保留换行符?
我有一个 python
脚本,它是通过一个 csh
脚本调用的(我不能使用 bash
)。这个 python 脚本会输出带有换行符的字符串,而我把这个输出存储在一个 csh 变量里。但是,一旦我把它存储到变量中,所有的换行符就都没了。下面是这两个脚本:
python 脚本 (pcmd.py)
def main(op):
if op == "h": # print help
# below newline character is getting lost
print ("Help first line\n second line.")
else: # print and later execute csh commands
print ("setenv SOME_ENV_VAR 123; setenv ANOTHER asd")
if __name__ == "__main__":
import sys
main(sys.argv[1])
csh 脚本 (pcmd.csh)
# store the py script in a variable
set pcmd="./pcmd.py $*"
# store the output of the first eval command
set output=`eval "$pcmd"`
# if output contains setenv, eval the output (csh commands)
if ( "$output" =~ *setenv* ) then
eval "${output}"
else # otherwise, print the output
echo "${output}" # Issue : losing newline chars, tried echo -e too but of no avail
执行过程
pcmd.csh h
expects: Help first line
second line.
actual: Help first line second line. # missing newline character
有没有人能指出脚本中缺少的部分?
1 个回答
3
这就是csh的工作方式。根据它的手册:
命令替换是通过用``包裹的命令来表示的。这样的命令输出会在空格、制表符和换行符处被分开,空的部分会被丢弃。输出的内容会被替换到原来的字符串位置。
在双引号(`")内的命令替换会保留空格和制表符;只有换行符会强制分开成新词。最后的单个换行符在任何情况下都不会强制分开成新词。因此,命令替换可能只输出一个单词的一部分,即使命令输出的是一整行。
默认情况下,从6.12版本开始,shell会把命令中的所有换行符和回车符替换为空格。如果取消这个设置(通过取消csubstnonl),换行符会像往常一样分开命令。
我最后一次使用csh是在1980年代中期。我不相信你想做的事情是可能的。csh是一个糟糕的shell,甚至比像Bash这样的POSIX shell还要差。即使你不能使用Bash,难道没有理由可以使用/bin/sh吗?或者更好的是,使用像Fish或Elvish这样的现代shell?
一个(部分)解决方案是使用双引号和数组捕获:
set output=("`$pcmd`")
这会让output
成为一个数组变量,每个元素是一行。然后你可以遍历这个数组,构建一个字符串,其中每个元素(行)之间用换行符分隔。注意我省略了eval
,因为在你的例子中它并不必要,而且非常危险。之所以称之为“部分”解决方案,是因为连续的换行符会被当作一个换行符处理。