【问题标题】:(bash) Indenting multiple lines of text to $VAR with cat?(bash) 用 cat 将多行文本缩进到 $VAR?
【发布时间】:2015-06-08 16:44:02
【问题描述】:

操作系统: Debian 7 Wheezy GNU\Linux
语言: Bash
已审核的文档: wiki/heredoc

什么有效:

cat > software.temp <<- EOF 
gparted 
baobab 
EOF 

什么没有

prefer="/etc/apt/preferences.d/${reponame}"
cat <<- EOF >> ${prefer}
Package: *
Pin: release l=Debian
Pin-Priority: 110
EOF

是的,我知道它是相反的,这可能是我没有让它工作的原因。基本上得到了古老的“找不到EOF”错误。请注意上面的每个块都用 TAB 缩进一次或多次。你可以看到我的代码here。我想知道是不是因为我试图引导输入/输出。

我可能以为是下面这样的东西,但这也没有用。

cat <<- EOF 
Package: *
Pin: release l=Debian
Pin-Priority: 110
EOF >> ${prefer}

【问题讨论】:

  • 您可以在 here-doc 之前或之后放置 I/O 重定向。如果你想通过管道输出 here-doc 的输出,管道必须在它之后:cat file - &lt;&lt;-EOF | whatever(其中whatever - 接收输出的命令 - 可以在此处结束后的单独行上 -文档)。如果您不使用带引号的“单词”形式,请注意不要将 here-doc 的单词括在引号中(&lt;&lt;- 'EOF'); the shell expands variables and $(...)` 命令替换(以及反引号版本)。
  • 我试过cat - &lt;&lt;- EOF | cat &gt;&gt; ${prefer},但这似乎不起作用(以EOF结尾。如果有帮助,您可以查看我的code
  • 您在使用 Debian?您确定您的脚本不是由dash 而不是bash 运行的吗?两者在某些方面表现不同,我不确定对 here-docs 的处理是否不是其中一种方式。当你运行bash -x add-debian-repos.sh 时你看到了什么?它与dash -x add-debian-repos.shsh -x add-debian-repos.sh 的行为是否不同?您能否创建一个 MCVE (Minimal, Complete, Verifiable Example),它不会修改任何人的系统管理内容,但会证明问题所在?
  • 还是和/bin/bash add-debian-repos一样。您可以将what workswhat does not work 进行比较以供参考。这些分别来自我的稳定/测试分支。谢谢你的帮助乔纳森。破折号给了我“未终止的引号字符串”,而 bash 给出了“意外的 EOF,同时寻找匹配的 `”'
  • &lt;&lt;&lt;&lt;- 与单词之间有一个空格。 POSIX 文档 (Here document) 没有空格。不过,这正在抓住稻草。我在我的机器(Ubuntu 14.04 LTS 衍生版本)上使用我的测试代码(只是松散地基于你的)找不到与 bash、dash 或 sh 的区别。从下载中,您似乎在缩进中有标签,所以您应该没问题。 (这给我带来了一个问题;本地编码标准是无制表符的,因此需要恶作剧才能将制表符放入文件中。)

标签: linux bash eof heredoc


【解决方案1】:

简答使用cat -A 并确保EOF 和行尾之间没有空格。


关于here-doc的两件事:

  1. 确保该行在您通常选择的字符串之后直接结束 EOF 但它可以是任何东西。

  2. cat &lt;&lt;-EOF 中的- 允许缩进,因此行可以以制表符开头,并且不会打印这些制表符。

例子:

tiago@dell:/tmp$ cat test1.sh
#!/bin/bash
cat << EOF
Hello here-doc
EOF

tiago@dell:/tmp$ cat test2.sh
#!/bin/bash
cat << EOF
Hello here-doc
EOF 

tiago@dell:/tmp$ bash test1.sh
Hello here-doc

tiago@dell:/tmp$ bash test2.sh
test2.sh: line 4: warning: here-document at line 2 delimited by end-of-file (wanted `EOF')
Hello here-doc
EOF 

这两个文件看起来相同,但在 test2.sh 上,EOF 后面有一个空格,在文本编辑器上看不到,但你可以使用 cat -A:

tiago@dell:/tmp$ cat -A test1.sh
#!/bin/bash$
cat << EOF$
Hello here-doc$
EOF$

tiago@dell:/tmp$ cat -A test2.sh
#!/bin/bash$
cat << EOF$
Hello here-doc$
EOF $

现在 WRT 缩进:

tiago@dell:/tmp$ cat test3.sh 
#!/bin/bash
cat << EOF
    Hello here-doc
EOF

cat <<-EOF 
    Hello here-doc (Indentation ignored)
EOF

tiago@dell:/tmp$ bash test3.sh
    Hello here-doc
Hello here-doc (Indentation ignored)

【讨论】:

  • 这是一些很棒的信息,但不能解决我的用例。我有一个指向我上面代码的链接。如果您不介意,请您看看您是否可以完成这项工作或建议如何处理它?当然,为了安全起见,只需将 funct_set_vars 中的 vars 更改为临时文件即可。
  • @ProfessorKaos64 看看@@paste.ubuntu.com/10731995 我隔离了你的场景。请注意,当您使用cat &lt;&lt;-EOF 时,只会忽略制表符,因此如果EOF 之前有空格而不是制表符,它将不起作用。让我知道这是否有帮助
  • 我之前和现在检查了块文本之后的 EOF 周围没有任何空格。虽然您的示例有 ^I ,但我有两个 ^I^I ,因为我有两个标签。我将整个部分支持一个 TAB 级别以产生你所拥有的。我的行尾 $ 是你的,以及我前面带有 ^I 的标签。我什至也将我喜欢的 $VAR 更改为 /tmp/file。什么会定义。告诉我我绝望了,如果你获得了我的测试脚本,并更改​​了顶部的perfer= var。如果这对你有用,我知道我做错了什么哈哈。您的测试文件代码确实有效。
  • @ProfessorKaos64 你把我们引向了完全错误的方向。你的脚本在第 117 行被破坏:echo -e "proceeding.\n"" 你有一个额外的双引号 :)
  • 天啊蒂亚戈!!!太好了,shellcheck.net 的双盲测试就这么多了!我不能感谢你。我刚刚知道它必须是代码中的其他内容。你让我今天一整天都感觉很好!也谢谢乔纳森!
猜你喜欢
  • 1970-01-01
  • 2021-10-02
  • 2021-10-10
  • 2023-03-22
  • 2020-02-20
  • 2013-09-13
  • 2014-02-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多