使用Fabric在受限shell中执行命令

2 投票
3 回答
3801 浏览
提问于 2025-04-17 12:31

我有一个这样的fabfile:

from fabric.api import * 

env.hosts = ['samplehost']
env.user = 'foo'
env.password = 'bar'
env.shell = ''

def exec_ls():
    run('ls')
    run('ls -l')

然后我得到了以下输出:

[samplehost] Executing task 'exec_ls'
[samplehost] run: ls
[samplehost] out: sample.txt

[samplehost] run: ls -l
[samplehost] out: rbash: ls -l: command not found

Fatal error: run() encountered an error (return code 127) while executing 'ls -l'

Aborting.
Disconnecting from samplehost... done.

用户 'foo' 的登录外壳是 '/bin/rbash'。

看起来如果我执行一个带参数的命令,它会被当作一个整体命令来处理(而不带参数的 'ls' 命令则可以正常工作)。

请注意,我使用了一个空的外壳,因为如果不这样做,Fabric 会尝试使用 '/bin/bash',而这在受限外壳中是不允许的。

在受限外壳中使用 Fabric 是可能的吗?

3 个回答

1

-检查目标机器的环境,使用

echo $SHELL

。假设你得到了这个:

/bin/sh

-然后在你的 python fabfile.py 文件中:

from fabric.api import env

env.shell = "/bin/sh -c"
2

在我的环境中,使用限制性shell作为Pure数组的一部分,似乎可以选择在运行函数时传递一个参数shell=False。

2

这个问题并不是因为使用了 rbash,而是因为 env.shell 的值是空的。要解决这个问题,可以使用:

env.shell = '/bin/rbash -l -c'

需要注意的是:

  • env.shell 的默认值是 /bin/bash -l -c,所以使用 /bin/rbash -l -c 是合理的
  • env.shell 被设置为空字符串时,命令不会通过任何 shell 执行
  • shell 的作用是把长字符串分割成命令和参数,如果没有 shell,整个字符串就会被当作一个命令来处理,而这个命令是找不到的,这就是之前发生的情况

撰写回答