无法从本地python脚本

时间:2016-09-13 19:23:21

标签: python python-2.7 ssh subprocess psql

我正在编写一个本地调用的脚本,以便在远程服务器上运行psql查询。我正在使用子进程模块在Python 2.7中编写脚本。我使用subprocess.Popen ssh到远程服务器并直接运行psql命令。我的本地机器是osx,我认为服务器是CentOS。

当我在本地调用我的脚本时,我收到一条错误psql: command not found。如果我在远程服务器上运行相同的psql命令,那么我会得到正确的查询结果。

我怀疑我的ssh代码可能有问题,所以我没有通过psql命令发送到远程服务器,而是尝试发送简单命令,如lscd,{{1} },甚至mkdir。所有这些都运行良好,所以我不认为我的代码存在问题,因为ssh是关于远程服务器的命令。

是否有人了解我的代码出了什么问题以及我为什么要回来scp我研究过并发现了之前的问题,但psql安装在远程服务器,因为我可以在那里手动运行psql命令。
Postgresql -bash: psql: command not found


从外部类文件:

psql: command not found



摘自导入上述类的本地脚本并将psql命令发送到远程服务器:

def db_cmd(self, query):
    # check that query ends in semicolon
    if query[-1] != ';':
        query = query + ';'

    formatted_query = 'psql ' + self.db_string + \
        ' -c "begin; ' + query + ' ' + self.db_mode + ';"'
    print formatted_query

    ssh = subprocess.Popen(['ssh', self.host, formatted_query],
                           shell=False,
                           stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE)
    result = ssh.stdout.readlines()
    if not result:
        error = ssh.stderr.readlines()
        print >>sys.stderr
        for e in error:
            print 'ERROR: %s' % e,
    else:
        for r in result:
            print r,



在本地运行我的脚本。 请注意,该脚本会打印出psql命令以进行调试。如果我复制并粘贴相同的psql命令并在远程服务器上运行它,我会得到正确的查询结果。

s = Jump(env, db_mode)
s.db_cmd('select * from student.students limit 5;')

由于

1 个答案:

答案 0 :(得分:2)

当您为远程系统上的交互式会话运行ssh时,ssh请求远程系统的PTY(伪TTY)。当您运行ssh以在远程系统上运行命令时,ssh默认不分配PTY。

让TTY / PTY改变shell初始化的方式。您的实际问题是您需要执行以下任何或所有操作才能在远程系统上运行psql:

  • 将一个或多个目录添加到命令路径中。
  • 向您的环境添加一个或多个环境变量。
  • 定义一个或多个别名。

您在shell启动文件(例如.bash_profile)中执行这些操作,并且它只发生在交互式会话中。当您使用ssh远程运行psql时,您的shell正在跳过允许psql运行的初始化。

有两种简单方法可以解决这个问题:

  1. 使用" -t"运行ssh;或" -tt"选项,这会导致ssh在远程系统上为psql分配TTY。
  2. 更改远程系统上的shell启动文件,以便在非交互式会话上执行必要的初始化。