使用 Bash 将一大块文本回显到文件中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6896025/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 20:49:17  来源:igfitidea点击:

Echo a large chunk of text to a file using Bash

bash

提问by thinkanotherone

I need to run a Bash script that can echo a 300 lines of Groovy script to a tmp file. What's the best way to do it ?

我需要运行一个可以将 300 行 Groovy 脚本回显到 tmp 文件的 Bash 脚本。最好的方法是什么?

My current workaround is putting the script file online and download it.

我目前的解决方法是将脚本文件联机并下载。

回答by Blagovest Buyukliev

Use the heredoc syntax to embed the other script within a shell script:

使用 heredoc 语法将其他脚本嵌入到 shell 脚本中:

cat > file.tmp <<'endmsg'
script goes here...
endmsg

回答by Chris Johnson

The heredoc approach is great, but you can't use it naively:

Heredoc 方法很棒,但你不能天真地使用它:

  • There are issues with not preserving spaces and tabs in the pasted content, which are hard to read on-screen, and may be triggered by the auto-cleanup functions of your text editor
  • If the end-of-heredoc marker you use occurs in the pasted content, the operation will end early -- problem if the content has its own heredoc and uses a common marker like 'EOF'.
  • 粘贴内容中不保留空格和制表符存在问题,难以在屏幕上阅读,并且可能由文本编辑器的自动清理功能触发
  • 如果您使用的 end-of-heredoc 标记出现在粘贴的内容中,操作将提前结束——如果内容有自己的 heredoc 并使用像“EOF”这样的通用标记,则会出现问题。

This means a naive heredoc approach can succeed or fail depending on the exact content that's pasted in. That violates the principle of least amazement and is dangerous since semi-random.

这意味着天真的heredoc方法可能会成功或失败,具体取决于粘贴的确切内容。这违反了最小惊奇原则,并且由于半随机而危险。

I prefer an approach where the content is captured with base64 uuencode first. This eliminates the possibility of different behavior depending on content, so you never have to think about this again.

我更喜欢先用 base64 uuencode 捕获内容的方法。这消除了根据内容出现不同行为的可能性,因此您无需再考虑这一点。

Safer approach:

更安全的方法:

  1. Identify the content to capture, say whatever.sh
  2. uuencode -m whatever.sh whatever.sh >tmp
  3. Paste the contents of tmp into the script wrapper
  4. Use a heredoc marker that can't occur in base64
  1. 确定要捕获的内容,随便说.sh
  2. uuencode -m whatever.sh whatever.sh >tmp
  3. 将 tmp 的内容粘贴到脚本包装器中
  4. 使用 base64 中不能出现的 heredoc 标记

The final script looks like:

最终脚本如下所示:

cat > file.tmp <<'_EOF'
begin-base64 644 whatever.sh
bHMgLWxSCmxzIC1sUgpscyAtbFIKbHMgLWxSCmxzIC1sUgpscyAtbFIKbHMg
LWxSCmxzIC1sUgpscyAtbFIKbHMgLWxSCmxzIC1sUgpscyAtbFIKbHMgLWxS
CmxzIC1sUgpscyAtbFIKbHMgLWxSCmxzIC1sUgpscyAtbFIKbHMgLWxSCmxz
IC1sUgpscyAtbFIK
====
_EOF
uudecode file.tmp

There is a tiny possibility that any line of uuencoded data could match your heredoc marker. You probably won't use markers that are 60 characters long :) but the last line can be shorter and there is a possibility the uuencoded content could accidentally match your marker, unless the marker uses a character (like underscore) that can't occur in base64 encoding. _EOFis always safe.

任何一行 uuencoded 数据都可能与您的 heredoc 标记匹配。您可能不会使用长度为 60 个字符的标记:) 但最后一行可以更短,并且 uuencoded 内容可能会意外匹配您的标记,除非标记使用了不可能出现的字符(如下划线)在 base64 编码中。 _EOF总是安全的。

It's also prudent to quote the heredoc marker like '_EOF'to prevent shell variable expansion in the block. I don't think a base64 encoded payload can ever inadvertently reference a shell variable since $isn't used in base64, but quoting eliminates this possibility. It also helps to establish the habit of always quoting the heredoc marker unless there's a reason you want shell expansion. This is another content-dependent behavior that's tricky since apparently random. ALWAYS quote your heredoc marker unless you know you want shell expansion within the content block!

引用 heredoc 标记也是谨慎的做法,'_EOF'以防止块中的 shell 变量扩展。我认为 base64 编码的有效负载不会无意中引用 shell 变量,因为$它没有在 base64 中使用,但引用消除了这种可能性。这也有助于养成总是引用heredoc 标记的习惯,除非有你想要shell 扩展的原因。这是另一种依赖于内容的行为,由于显然是随机的,因此很棘手。总是引用你的 heredoc 标记,除非你知道你想要在内容块中扩展 shell!

The above is a manual procedure. It's easy to automate the same using templates.

以上是手动过程。使用模板可以轻松实现相同的自动化。

回答by Theodore R. Smith

When you want to output to a file that requires you to use sudo, the answer is totally non-obvious!

当你想输出到一个需要你使用的文件时,sudo答案是完全不明显的!

sudo tee /etc/php/conf.d/xdebug.ini > /dev/null <<'TXT'
zend_extension=xdebug.so
xdebug.remote_enable=on
xdebug.remote_autostart=on
xdebug.remote_host=127.0.0.1
xdebug.remote_port=9000
xdebug.remote_handler=dbgp
TXT