将命令作为输入传递给另一个命令(su、ssh、sh 等) [英] Pass commands as input to another command (su, ssh, sh, etc)

查看:27
本文介绍了将命令作为输入传递给另一个命令(su、ssh、sh 等)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个脚本,我需要在其中启动一个命令,然后将一些附加命令作为命令传递给该命令.我试过了

I have a script where I need to start a command, then pass some additional commands as commands to that command. I tried

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

...但它不起作用:su 成功,但是命令提示符只是盯着我看.如果我在提示符下输入 exitechowho am i 等开始执行!并且 echo done. 根本没有被执行.

... but it doesn't work: The su succeeds, but then the command prompt is just staring at me. If I type exit at the prompt, the echo and who am i etc start executing! And the echo done. doesn't get executed at all.

同样地,我需要让它通过 ssh 工作:

Similarly, I need for this to work over ssh:

ssh remotehost
# this should run under my account on remotehost
su
## this should run as root on remotehost
whoami
exit
## back
exit
# back

我该如何解决这个问题?

How do I solve this?

我正在寻找以一般方式解决此问题的答案,并且不特定于 sussh.目的是让这个问题成为一个 此特定模式的规范.

I am looking for answers which solve this in a general fashion, and which are not specific to su or ssh in particular. The intent is for this question to become a canonical for this particular pattern.

推荐答案

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

A shell script is a sequence of commands. The shell will read the script file, and execute those commands one after the other.

在通常情况下,这里没有意外;但一个常见的初学者错误是假设 some 命令将从 shell 接管,并开始在脚本文件中执行以下命令,而不是当前运行此脚本的 shell.但这不是它的工作原理.

In the usual case, there are no surprises here; but a frequent beginner error is assuming that some commands will take over from the shell, and start executing the following commands in the script file instead of the shell which is currently running this script. But that's not how it works.

基本上,脚本完全像交互式命令一样工作,但是需要正确理解它们究竟是如何工作的.交互地,shell 读取一个命令(来自标准输入),运行该命令(使用来自标准输入的输入),当它完成时,它读取另一个命令(来自标准输入).

Basically, scripts work exactly like interactive commands, but how exactly they work needs to be properly understood. Interactively, the shell reads a command (from standard input), runs that command (with input from standard input), and when it's done, it reads another command (from standard input).

现在,当执行一个脚本时,标准输入仍然是终端(除非你使用了重定向)但是命令是从脚本文件中读取的,而不是从标准输入中读取的.(相反确实会非常麻烦 - 任何 read 都会消耗脚本的下一行,cat 会吞掉脚本的所有其余部分,并且没有办法与它交互!)脚本文件包含执行它的 shell 实例的命令(尽管您当然仍然可以使用 here 文档等将输入嵌入为命令参数).

Now, when executing a script, standard input is still the terminal (unless you used a redirection) but the commands are read from the script file, not from standard input. (The opposite would be very cumbersome indeed - any read would consume the next line of the script, cat would slurp all the rest of the script, and there would be no way to interact with it!) The script file only contains commands for the shell instance which executes it (though you can of course still use a here document etc to embed inputs as command arguments).

换句话说,这些被误解"的命令(susshshsudobash 等)单独运行时(不带参数)将启动交互式 shell,在交互式会话中,这显然没问题;但是当从脚本运行时,这通常不是您想要的.

In other words, these "misunderstood" commands (su, ssh, sh, sudo, bash etc) when run alone (without arguments) will start an interactive shell, and in an interactive session, that's obviously fine; but when run from a script, that's very often not what you want.

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

All of these commands have ways to accept commands by ways other than in an interactive terminal session. Typically, each command supports a way to pass it commands as options or arguments:

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

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

Many of these commands will also accept commands on standard input:

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

这也方便您使用此处的文档:

which also conveniently allows you to use here documents:

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

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

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

For commands which accept a single command argument, that command can be sh or bash with multiple commands:

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

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

As an aside, you generally don't need an explicit exit because the command will terminate anyway when it has executed the script (sequence of commands) you passed in for execution.

这篇关于将命令作为输入传递给另一个命令(su、ssh、sh 等)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆