我正在尝试编写在远程计算机上运行的脚本。
由于该脚本很复杂,因此我将其分解成一些函数,然后使用typeset
复制到了脚本中。
运行脚本时,出现以下错误:
bash: -c: line 4: syntax error: unexpected end of file
但是,文件没有意外结束!我确保所有if
都有fi
,所有{
都有}
,等等。
我确保所有缩进都使用制表符(和空格),并确保换行符一致。
我已将代码简化为一个最小的示例。似乎某个函数有效,它需要以if
fi
或while
done
之类的构造结尾。
这是行不通的。
func() {
ls ~/
}
ssh -A -T user@machine_ip '
'$(typeset -f func)'
func
'
第4行与}
函数的结尾func
重合(因为在远程计算机上发生此错误,因此对ssh -A -T...
之后的行进行计数)。
但是,如果我们在函数末尾添加一个构造,则会按预期方式打印主目录。
func() {
ls ~/
if [[ 1 ]]; then
echo "Hello"
fi
}
或
func() {
ls ~/
while false; do
echo "Here"
done
}
typeset -f func
的输出是
func ()
{
ls --color=auto ~/;
if [[ -n 1 ]]; then
echo "Hello";
fi
}
我正在运行Ubuntu 18.04 LTS,远程计算机正在运行Centos 6。
答案 0 :(得分:1)
因为如果让bash玩空格,它就会发挥作用。让我解释一下:
$(typeset -f func)
将求值typeset -f func
并将其输出插入当前命令行。如果不加引号,它也将细分为参数,这将使所有空白折叠为一个空格,这是一个副作用。因此,如果typeset -f func
可以打印(就像在我的系统上一样)
func ()
{
/bin/ls --color=auto ~/
}
$(typeset -f func)
带来的好处
func () { /bin/ls --color=auto ~/ }
(如果您不相信我,请尝试echo $(typeset -f func)
:D)
现在,bash对于接受模糊的代码确实很害羞。例如,您可能知道这不是语法上的:
if true then echo "yes" fi
这是:
if true; then echo "yes"; fi
以同样的方式,函数定义的右括号很挑剔。因此,这可行:
func () { /bin/ls --color=auto ~/; }
但这不是:
func () { /bin/ls --color=auto ~/ }
由于某种原因,bash可以使用括号前的关键字作为罚款。
func () { /bin/ls --color=auto ~/; if [[ -n 1 ]]; then echo "Hello"; fi }
func () { /bin/ls --color=auto ~/; while false; do echo "Here"; done }
要解决这个问题,请尝试不要从命令行发送东西,而是从重定向发送东西,
ssh -A -T user@machine_ip < <(typeset -f func; echo func)
或者最简单的方法是,使用双引号防止bash
空格的倒角:
ssh -A -T user@machine_ip "$(typeset -f func)
func"
答案 1 :(得分:0)
首先,引号的使用方式对我来说毫无意义。
ssh -A -T user@machine_ip '
'$(typeset -f func)'
func
'
第2个'仅回显一个空行。 (第二个'关闭第一个逻辑?)
反正。
$(typeset -f func)
func
上面的代码将执行func 2次。 至少这就是它对我有效的方式
....