猿问

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

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

我有一个脚本,在那里我需要启动一个命令,然后传递一些附加的命令。作为命令为了那个命令。我试过

su
echo I should be root now:who am I
exit
echo done.

..但是它不起作用:su成功了,但是命令提示符只是盯着我看。如果我打字exit在提示下,echowho 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

我该怎么解决这个问题?

我正在寻找解决这一问题的一般方式的答案,而这些答案并不是特定于sussh特别是。目的是让这个问题成为典范为这个特殊的模式。


12345678_0001
浏览 2193回答 3
3回答

RISEBY

shell脚本是一系列命令。shell将读取脚本文件,并依次执行这些命令。在通常情况下,这里没有任何意外;但是一个经常出现的初学者错误是假设一些命令将接管shell,并开始在脚本文件中执行以下命令,而不是当前运行此脚本的shell。但这不是它的工作方式。基本上,脚本起作用一点儿没错比如交互式命令,但是一点儿没错他们的工作需要被正确的理解。交互式地,shell读取一个命令(从标准输入),运行该命令(输入来自标准输入),当它完成时,它读取另一个命令(从标准输入)。现在,在执行脚本时,标准输入仍然是终端(除非使用重定向)但是命令是从脚本文件中读取的,而不是从标准输入中读取的。(相反的情况确实很麻烦-任何read会消耗脚本的下一行,cat会将脚本的其余部分都删除,因此无法与其进行交互!)脚本文件只包含执行它的shell实例的命令(当然,您仍然可以使用这里的文档等将输入作为命令参数嵌入)。换句话说,这些“误解”命令(su,&nbsp;ssh,&nbsp;sh,&nbsp;sudo,&nbsp;bash(等等)单独运行(没有参数)将启动交互式shell,而在交互会话中,这显然很好;但从脚本运行时,这通常不是您想要的。所有这些命令都有通过交互终端会话以外的其他方式接受命令的方法。通常,每个命令都支持将其命令作为选项或参数传递的方式:su&nbsp;root&nbsp;-c&nbsp;'who&nbsp;am&nbsp;i'ssh&nbsp;user@remote&nbsp;uname&nbsp;-a sh&nbsp;-c&nbsp;'who&nbsp;am&nbsp;i;&nbsp;echo&nbsp;success'其中许多命令还将接受标准输入的命令:printf&nbsp;'uname&nbsp;-a;&nbsp;who&nbsp;am&nbsp;i;&nbsp;uptime'&nbsp;|&nbsp;su printf&nbsp;'uname&nbsp;-a;&nbsp;who&nbsp;am&nbsp;i;&nbsp;uptime'&nbsp;|&nbsp;ssh&nbsp;user@remote printf&nbsp;'uname&nbsp;-a;&nbsp;who&nbsp;am&nbsp;i;&nbsp;uptime'&nbsp;|&nbsp;sh它还方便地允许您在这里使用文档:ssh&nbsp;user@remote&nbsp;<<'____HERE' &nbsp;&nbsp;&nbsp;&nbsp;uname&nbsp;-a &nbsp;&nbsp;&nbsp;&nbsp;who&nbsp;am&nbsp;i &nbsp;&nbsp;&nbsp;&nbsp;uptime ____HERE sh&nbsp;<<'____HERE' &nbsp;&nbsp;&nbsp;&nbsp;uname&nbsp;-a &nbsp;&nbsp;&nbsp;&nbsp;who&nbsp;am&nbsp;i &nbsp;&nbsp;&nbsp;&nbsp;uptime ____HERE对于接受单个命令参数的命令,该命令可以是sh或bash使用多个命令:sudo&nbsp;sh&nbsp;-c&nbsp;'uname&nbsp;-a;&nbsp;who&nbsp;am&nbsp;i;&nbsp;uptime'顺便说一句,您通常不需要显式的exit因为该命令在执行完脚本(命令序列)后无论如何都会终止。

宝慕林4294392

加到三叉戟氏回答:重要的是要记住,脚本中格式化为针对另一个shell的这里文档的部分是在具有自己的环境(甚至是在另一台机器上)的不同shell中执行的。如果脚本中的该块包含参数展开、命令替换和/或算术扩展,则必须使用shell的here-Document工具略有不同,这取决于您希望在何处执行这些扩展。1.所有扩展都必须在父shell的范围内执行。然后,此处文档的分隔符必须是未报价.command&nbsp;<<DELIMITER...DELIMITER例子:#!/bin/basha=0mylogin=$(whoami)sudo&nbsp;sh&nbsp;<<END &nbsp;&nbsp;&nbsp;&nbsp;a=1 &nbsp;&nbsp;&nbsp;&nbsp;mylogin=$(whoami) &nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;a=$a &nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;mylogin=$mylogin END echo&nbsp;a=$a echo&nbsp;mylogin=$mylogin产出:a=0mylogin=leon a=0mylogin=leon2.所有展开必须在子shell的范围内执行。然后,此处文档的分隔符必须是引文.command&nbsp;<<'DELIMITER'...DELIMITER例子:#!/bin/basha=0mylogin=$(whoami)sudo&nbsp;sh&nbsp;<<'END' &nbsp;&nbsp;&nbsp;&nbsp;a=1 &nbsp;&nbsp;&nbsp;&nbsp;mylogin=$(whoami) &nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;a=$a &nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;mylogin=$mylogin END echo&nbsp;a=$a echo&nbsp;mylogin=$mylogin产出:a=1mylogin=root a=0mylogin=leon3.必须在子shell中执行一些扩展,在父shell中执行一些扩展。然后,此处文档的分隔符必须是未报价你必须转义必须在子shell中执行的展开表达式。.例子:#!/bin/basha=0mylogin=$(whoami)sudo&nbsp;sh&nbsp;<<END &nbsp;&nbsp;&nbsp;&nbsp;a=1 &nbsp;&nbsp;&nbsp;&nbsp;mylogin=\$(whoami) &nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;a=$a &nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;mylogin=\$mylogin END echo&nbsp;a=$a echo&nbsp;mylogin=$mylogin产出:a=0mylogin=root a=0mylogin=leon
随时随地看视频慕课网APP

相关分类

Python
我要回答