以 root 身份调用 bash 函数但给出“意外的文件结尾”

use*_*657 1 bash sudo su

为什么最后一个示例会抛出错误,而其他示例却可以工作?在任何情况下都会调用 Bash。

#!/bin/bash

function hello {
    echo "Hello! user=$USER, uid=$UID, home=$HOME"; 
}

# Test that it works.
hello

# ok
bash -c "$(declare -f hello); hello"

# ok
sudo su $USER bash -c "$(declare -f hello); hello"

# error: bash: -c: line 1: syntax error: unexpected end of file
sudo -i -u $USER bash -c "$(declare -f hello); hello"
Run Code Online (Sandbox Code Playgroud)

Léa*_*ris 5

由于-ior--login开关而失败:

好像用-x调试时

$ set -x
$ sudo -i -u $USER bash -c "$(declare -f hello); hello"
++ declare -f hello
+ sudo -i -u lea bash -c 'hello () 
{ 
    echo "Hello! user=$USER, uid=$UID, home=$HOME"
}; hello'
Run Code Online (Sandbox Code Playgroud)

现在,如果手动执行此操作,则会导致相同的错误:

sudo -i -u lea bash -c 'hello () 
{ 
    echo "Hello! user=$USER, uid=$UID, home=$HOME"
}; hello'
Run Code Online (Sandbox Code Playgroud)

现在让我们做一个简单的微小改变,让它发挥作用:

sudo -i -u lea bash -c 'hello () 
{ 
    echo "Hello! user=$USER, uid=$UID, home=$HOME";}; hello'
Run Code Online (Sandbox Code Playgroud)

原因是它sudo -i像交互式 shell 一样运行一切。这样做时,每个换行符都会declare -f hello在内部转换为空格。当大括号代码块在同一行时,在右大括号之前需要一个分号,但declare -f funcname没有提供分号,因为它在新行处使用右大括号扩展了函数源。

现在让这个行为变得非常简单:

$ sudo bash -c 'echo hello 
echo world'
hello
world
Run Code Online (Sandbox Code Playgroud)

它执行这两个echo语句,因为它们由换行符分隔。

但:

$ sudo -i bash -c 'echo hello 
echo world'
hello echo world
Run Code Online (Sandbox Code Playgroud)

它执行第一个echo将所有内容打印为参数的语句,因为换行符已被空格替换。