为了账号安全,请及时绑定邮箱和手机立即绑定

将命令作为输入传递到另一个命令(su、ssh、sh等)

将命令作为输入传递到另一个命令(su、ssh、sh等)

12345678_0001 2019-06-19 16:40:15
将命令作为输入传递到另一个命令(su、ssh、sh等)我有一个脚本,在那里我需要启动一个命令,然后传递一些附加的命令。作为命令为了那个命令。我试过su echo I should be root now:who am I exit echo done...但是它不起作用:su成功了,但是命令提示符只是盯着我看。如果我打字exit在提示下,echo和who am i等等开始执行!而echo done.根本没有被处决。同样的,我需要解决这个问题ssh:ssh remotehost# this should run under my account on remotehostsu## this should run as root on remotehostwhoami exit## backexit# back我该怎么解决这个问题?我正在寻找解决这一问题的一般方式的答案,而这些答案并不是特定于su或ssh特别是。目的是让这个问题成为典范为这个特殊的模式。
查看完整描述

3 回答

?
RISEBY

TA贡献1856条经验 获得超5个赞

shell脚本是一系列命令。shell将读取脚本文件,并依次执行这些命令。

在通常情况下,这里没有任何意外;但是一个经常出现的初学者错误是假设一些命令将接管shell,并开始在脚本文件中执行以下命令,而不是当前运行此脚本的shell。但这不是它的工作方式。

基本上,脚本起作用一点儿没错比如交互式命令,但是一点儿没错他们的工作需要被正确的理解。交互式地,shell读取一个命令(从标准输入),运行该命令(输入来自标准输入),当它完成时,它读取另一个命令(从标准输入)。

现在,在执行脚本时,标准输入仍然是终端(除非使用重定向)但是命令是从脚本文件中读取的,而不是从标准输入中读取的。(相反的情况确实很麻烦-任何read会消耗脚本的下一行,cat会将脚本的其余部分都删除,因此无法与其进行交互!)脚本文件包含执行它的shell实例的命令(当然,您仍然可以使用这里的文档等将输入作为命令参数嵌入)。

换句话说,这些“误解”命令(susshshsudobash(等等)单独运行(没有参数)将启动交互式shell,而在交互会话中,这显然很好;但从脚本运行时,这通常不是您想要的。

所有这些命令都有通过交互终端会话以外的其他方式接受命令的方法。通常,每个命令都支持将其命令作为选项或参数传递的方式:

su root -c 'who am i'ssh user@remote uname -a
sh -c 'who am i; echo success'

其中许多命令还将接受标准输入的命令:

printf 'uname -a; who am i; uptime' | su
printf 'uname -a; who am i; uptime' | ssh user@remote
printf 'uname -a; who am i; uptime' | sh

它还方便地允许您在这里使用文档:

ssh user@remote <<'____HERE'
    uname -a
    who am i
    uptime
____HERE

sh <<'____HERE'
    uname -a
    who am i
    uptime
____HERE

对于接受单个命令参数的命令,该命令可以是shbash使用多个命令:

sudo sh -c 'uname -a; who am i; uptime'

顺便说一句,您通常不需要显式的exit因为该命令在执行完脚本(命令序列)后无论如何都会终止。


查看完整回答
反对 回复 2019-06-19
?
宝慕林4294392

TA贡献2021条经验 获得超8个赞

加到三叉戟回答:

重要的是要记住,脚本中格式化为针对另一个shell的这里文档的部分是在具有自己的环境(甚至是在另一台机器上)的不同shell中执行的。

如果脚本中的该块包含参数展开、命令替换和/或算术扩展,则必须使用shell的here-Document工具略有不同,这取决于您希望在何处执行这些扩展。

1.所有扩展都必须在父shell的范围内执行。

然后,此处文档的分隔符必须是未报价.

command <<DELIMITER...DELIMITER

例子:

#!/bin/basha=0mylogin=$(whoami)sudo sh <<END
    a=1
    mylogin=$(whoami)
    echo a=$a
    echo mylogin=$mylogin
END
echo a=$a
echo mylogin=$mylogin

产出:

a=0mylogin=leon
a=0mylogin=leon

2.所有展开必须在子shell的范围内执行。

然后,此处文档的分隔符必须是引文.

command <<'DELIMITER'...DELIMITER

例子:

#!/bin/basha=0mylogin=$(whoami)sudo sh <<'END'
    a=1
    mylogin=$(whoami)
    echo a=$a
    echo mylogin=$mylogin
END
echo a=$a
echo mylogin=$mylogin

产出:

a=1mylogin=root
a=0mylogin=leon

3.必须在子shell中执行一些扩展,在父shell中执行一些扩展。

然后,此处文档的分隔符必须是未报价你必须转义必须在子shell中执行的展开表达式。.

例子:

#!/bin/basha=0mylogin=$(whoami)sudo sh <<END
    a=1
    mylogin=\$(whoami)
    echo a=$a
    echo mylogin=\$mylogin
END
echo a=$a
echo mylogin=$mylogin

产出:

a=0mylogin=root
a=0mylogin=leon


查看完整回答
反对 回复 2019-06-19
  • 3 回答
  • 0 关注
  • 2192 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信