标签: here-document

如何从 Bash 以 root 身份登录并执行操作

这是我的简单 bash:

cat test.sh

#!/bin/bash 
echo "hello"
su - root -c /path/to/script.sh <<EOF
password                              
EOF
whoami
echo "good bye"
Run Code Online (Sandbox Code Playgroud)

但我收到此错误:

./test.sh
hello
su: must be run from a terminal
<current-user>
good bye
Run Code Online (Sandbox Code Playgroud)

(或者)

cat test2.sh
#!/bin/bash 
echo "hello"
sudo su <<EOF
password                              
EOF
whoami
echo "good bye"
Run Code Online (Sandbox Code Playgroud)

又一个错误

(或者)

cat test3.sh
#!/bin/bash 
echo "hello"
su root <<EOF
password                              
EOF
whoami
echo "good bye"
Run Code Online (Sandbox Code Playgroud)

又是错误...

当我尝试:

#!/bin/bash
echo "hello"
sudo -s <<EOF
<password>
echo Now I am root
id                                                                      
echo "yes!" …
Run Code Online (Sandbox Code Playgroud)

shell bash su sudo here-document

4
推荐指数
1
解决办法
9万
查看次数

如何将heredoc输出设置为局部变量

我正在尝试在 heredoc 中将其输出设置为局部变量,如下所示:

REMOTE_OUTPUT=$(ssh remote@server /bin/bash << EOF
  find my/path/ -type f -not -path my/path/*/ -type f -mtime -0 | while read filename; do
        if grep "ERROR" $filename; then
            filenamebase=$(basename "$filename")
            echo -e "\n----------------------------------------------------------\n\n$filenamebase failure:\n"
            grep -n "ERROR" "$filename" | sed G
        fi
    done
EOF)
Run Code Online (Sandbox Code Playgroud)

但是即使 find&grep 循环正确并且确实应该返回输出,该变量仍然为空。

(否则我也有兴趣将 heredoc 的输出写入本地文件。)

shell bash here-document

4
推荐指数
1
解决办法
6990
查看次数

这里文档错误我无法理解(“以文件结尾分隔”)

我在 Bash 中执行以下代码:

bash /dev/fd/10 10<<-'SES'

    cat <<EMR >> /etc/apache2/apache2.conf
        #
        <Directory /var/www/>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
        </Directory>
        EMR

SES
Run Code Online (Sandbox Code Playgroud)

但是执行中断了,我得到:

警告:第 2 行的此处文档由文件结尾分隔(需要“EMR”)

  • 我不明白错误是什么意思,我已经-在操作符和包含 heredoc 的名称之间添加以允许列表。
  • 我确信没有空格揭幕战(运营商+名)或之后的分隔符

注意:如果您复制上面的代码在您的计算机中进行测试,您需要将所有前导空格更改为制表符(制表符),因为StackExchange将原始制表符更改为空格。


排除的可能原因:

造成这种情况的可能原因有多种,以下是我排除的一些原因:

1.有问题的隐藏字符:

我用 Notepad++ 编辑文件并打开“显示所有符号”模式以确保所有缩进都是基于表格的(见红色箭头)并且所有行尾字符(EOL)都是LF基于 unix 的(没有任何CR字符) ):

在此处输入图片说明

而且,编码是UTF-8,所以这不是编码问题。

2. 伪破折号 ( <<-):

这似乎为加连字符(<<-)不会做剥离所有领先的标签,因为当我手动删除所有领先的标签其工作任何(或所有领先的标签每个定界符之前)的定界符不按预期方式工作。人们可以认为连字符并不是真正的破折号,但为什么不是呢?我没有办法验证这一点。

3. 重击错误:

其他不使用 Windows 和使用不同的包含 …

bash here-document

4
推荐指数
2
解决办法
1万
查看次数

使用 /dev/stdin 和 heredoc 从命令行传递文件

我很好奇 heredocs 如何作为文件传递给命令行实用程序背后的理论。

最近,我发现我可以将文件作为 heredoc 传递。

例如:

awk '{ split($0, arr, " "); print arr[2] }' <<EOF
foo bar baz
EOF
bar
Run Code Online (Sandbox Code Playgroud)

出于以下几个原因,这对我来说是有利的:

  • Heredocs 提高了多行输入的可读性。
  • 我不需要记住每个实用程序标志来从命令行传递文件内容。
  • 我可以在给定的文件中使用单引号和双引号。
  • 我可以控制外壳扩展。

例如:

ruby <<EOF
puts "'hello $HOME'"
EOF
'hello /Users/mbigras'

ruby <<'EOF'
puts "'hello $HOME'"
EOF
'hello $HOME'
Run Code Online (Sandbox Code Playgroud)

我不清楚发生了什么。似乎shell认为heredoc是一个内容等于heredoc值的文件。我已经将这种技术与 cat 一起使用,但我仍然不确定发生了什么:

cat <<EOL
hello world
EOL
hello world
Run Code Online (Sandbox Code Playgroud)

我知道cat打印文件的内容,所以大概这个 heredoc 是某种临时文件。

当我“将heredoc传递给命令行程序”时,我对究竟发生了什么感到困惑。

这是使用ansible-playbook的示例。我将实用程序作为 heredoc 传递给剧本;但是它失败了,如使用所示echo $?

ansible-playbook -i localhost, -c local <<EOF &>/dev/null
---
- hosts: all …
Run Code Online (Sandbox Code Playgroud)

command-line bash here-document ansible

4
推荐指数
1
解决办法
5563
查看次数

在 SSH 调用中使用函数的输出(本地定义)

我创建了一个函数

function getqueue() {
    urlqueuename="urlcall"    
    ouput=`curl $urlqueuename`
    queue=$(echo $ouput | jq -r '.queueName')
    echo $queue
}
Run Code Online (Sandbox Code Playgroud)

我正在使用脚本中的 ssh 调用,例如:

ssh -T -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i "$HOME_DIR/<pemfile>" $username@$IP<<EOF
queue=$(getqueue)
echo "Queue name : $queue"
EOF
Run Code Online (Sandbox Code Playgroud)

但是队列为空,也尝试$(typeset -f)在远程调用中使用函数,但变量仍然为空

任何有关相同的指导将不胜感激。

ssh shell-script quoting here-document

4
推荐指数
1
解决办法
1171
查看次数

如何处理多行字符串和字符串插值?

假设我想在某处有一个多行字符串的模板:

I have some
text with ${placeholders}
in this and some ${different}
ones ${here} and ${there}
Run Code Online (Sandbox Code Playgroud)

用用户输入替换占位符的最佳方法是什么?here-documents 会很好用吗?

string here-document

4
推荐指数
2
解决办法
6172
查看次数

导出函数中子函数中的 Heredoc 失败

这有效:

#!/bin/bash

foo() {
    gen() {
        cat <<EOF
bar
EOF
        true
    }
    gen
}

foo
export -f foo
bash -c foo
Run Code Online (Sandbox Code Playgroud)

这在最后一行失败:

#!/bin/bash

foo() {
    gen() {
        cat <<EOF
bar
EOF
    }
    gen
}

foo
export -f foo
bash -c foo
Run Code Online (Sandbox Code Playgroud)

给予:

bar
bash: foo: line 9: syntax error: unexpected end of file
bash: error importing function definition for `foo'
bash: foo: command not found
Run Code Online (Sandbox Code Playgroud)

为什么true需要最后一个?

$ bash --version
GNU bash, version 5.0.17(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2019 Free …
Run Code Online (Sandbox Code Playgroud)

bash here-document

4
推荐指数
1
解决办法
83
查看次数

猫在里面写带有“$”的文字

我想将配置信息写入一个包含美元符号 ( $)的特定文件。这似乎是一个问题。

这是我所做的:

$ cat >> /etc/nginx/nginx.conf <<EOF
# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user              nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log;
#error_log  /var/log/nginx/error.log  notice;
#error_log  /var/log/nginx/error.log  info;

pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    ## Detect when HTTPS is used
    map $scheme $https {
      default off;
      https on;
    }
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" …
Run Code Online (Sandbox Code Playgroud)

shell quoting cat here-document

3
推荐指数
1
解决办法
1069
查看次数

对于输入重定向,bash/zsh &lt;&lt;&lt;"$(&lt;file)" 和传统的 &lt;file 之间是否存在功能差异?

我只询问与文件中的传统输入重定向具有类似效果的用法。

<<<"$(<file)"
Run Code Online (Sandbox Code Playgroud)

据我所知相当于

<file
Run Code Online (Sandbox Code Playgroud)

在我看来,这些在功能上是等效的。在低级别看来,<<< here 文档实际上可能会导致更多的数据副本一次在内存中。

我知道 bash 和 zsh 中都存在这种类型的重定向,但我不熟悉它的实现方式,尽管我看到 zsh 联机帮助页包含一些实现细节。

bash zsh io-redirection command-substitution here-document

3
推荐指数
1
解决办法
885
查看次数

单行 heredocument - 在 Bash 中可能吗?

我希望cat在一行中运行一个heredocument,而不是 3 行的自然语法(开场白、内容和分隔符)。我这样做的需要主要是美观,因为重定向的内容旨在成为手册文本文件的一部分,我想在该特定文件中尽可能多地保存行)。

cat <<< TEST > ~/myRep/tiesto tiesto TEST(我通常会分成 3 部分)会导致错误:

tiesto: 没有这样的文件或目录

测试:没有这样的文件或目录。

甚至可以在 Bash 中执行一行 heredocuments 吗?

here-document here-string

3
推荐指数
1
解决办法
4400
查看次数