无法从本地 python 脚本在远程服务器上 运行 psql 命令
Unable to run psql commands on remote server from local python script
我正在编写一个在本地调用的脚本,用于 运行 远程服务器上的 psql 查询。我正在使用 subprocess 模块在 Python 2.7 中编写脚本。我正在使用 subprocess.Popen 通过 ssh 连接到远程服务器并直接 运行 一个 psql 命令。我的本地机器是 osx,我认为服务器是 CentOS。
当我在本地调用我的脚本时,我收到一条错误 psql: command not found
。如果我 运行 在远程服务器上执行完全相同的 psql 命令,那么我会得到正确的查询结果。
我怀疑我的 ssh 代码可能有问题,所以我没有将 psql 命令发送到远程服务器,而是尝试发送简单的命令,如 ls
、cd
、mkdir
,甚至 scp
。所有这些都工作正常,所以我认为我的代码没有问题,ssh 通过命令发送到远程服务器。
有人知道我的代码出了什么问题以及我为什么要回来吗psql: command not found
?我研究并发现了这个较早的 SO 问题,但是 psql 是安装在远程服务器上,事实证明我可以在那里手动 运行 psql 命令。
Postgresql -bash: psql: command not found
来自外部 class 文件:
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,
摘自在 class 上方导入并向远程服务器发送 psql 命令的本地脚本:
s = Jump(env, db_mode)
s.db_cmd('select * from student.students limit 5;')
运行 我的本地脚本。
请注意,该脚本会打印出 psql 命令以进行调试。如果我复制并粘贴相同的 psql 命令并将其 运行 复制到远程服务器上,我会得到正确的查询结果。
$ ./script.py 1 PROD ROLLBACK
psql -h <server_host> -d <db_name> -U <db_user> -p <port> -c "begin; select * from student.students limit 5; ROLLBACK;"
ERROR: bash: psql: command not found
谢谢
当您 运行 在远程系统上使用 ssh 进行交互式会话时,ssh 会为远程系统请求 PTY(伪 TTY)。当您 运行 ssh 到 运行 远程系统上的命令时,默认情况下 ssh 不会分配 PTY。
拥有 TTY/PTY 会改变您的 shell 初始化自身的方式。您的实际问题是您需要对远程系统上的 运行 psql 执行以下任何或所有操作:
- 将一个或多个目录添加到您的命令路径。
- 为您的环境添加一个或多个环境变量。
- 定义一个或多个别名。
您在 shell 启动文件(例如。bash_profile)中执行这些操作,并且它只发生在交互式会话中。当您远程使用 ssh 到 运行 psql 时,您的 shell 正在跳过允许 psql 到 运行.
的初始化
有两种简单的方法可以解决此问题:
- 运行 带有“-t”或“-tt”选项的 ssh,这会导致 ssh 在远程系统上为 psql 分配一个 TTY。
- 更改远程系统上的 shell 启动文件以对非交互式会话执行必要的初始化。
我正在编写一个在本地调用的脚本,用于 运行 远程服务器上的 psql 查询。我正在使用 subprocess 模块在 Python 2.7 中编写脚本。我正在使用 subprocess.Popen 通过 ssh 连接到远程服务器并直接 运行 一个 psql 命令。我的本地机器是 osx,我认为服务器是 CentOS。
当我在本地调用我的脚本时,我收到一条错误 psql: command not found
。如果我 运行 在远程服务器上执行完全相同的 psql 命令,那么我会得到正确的查询结果。
我怀疑我的 ssh 代码可能有问题,所以我没有将 psql 命令发送到远程服务器,而是尝试发送简单的命令,如 ls
、cd
、mkdir
,甚至 scp
。所有这些都工作正常,所以我认为我的代码没有问题,ssh 通过命令发送到远程服务器。
有人知道我的代码出了什么问题以及我为什么要回来吗psql: command not found
?我研究并发现了这个较早的 SO 问题,但是 psql 是安装在远程服务器上,事实证明我可以在那里手动 运行 psql 命令。
Postgresql -bash: psql: command not found
来自外部 class 文件:
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,
摘自在 class 上方导入并向远程服务器发送 psql 命令的本地脚本:
s = Jump(env, db_mode)
s.db_cmd('select * from student.students limit 5;')
运行 我的本地脚本。
请注意,该脚本会打印出 psql 命令以进行调试。如果我复制并粘贴相同的 psql 命令并将其 运行 复制到远程服务器上,我会得到正确的查询结果。
$ ./script.py 1 PROD ROLLBACK
psql -h <server_host> -d <db_name> -U <db_user> -p <port> -c "begin; select * from student.students limit 5; ROLLBACK;"
ERROR: bash: psql: command not found
谢谢
当您 运行 在远程系统上使用 ssh 进行交互式会话时,ssh 会为远程系统请求 PTY(伪 TTY)。当您 运行 ssh 到 运行 远程系统上的命令时,默认情况下 ssh 不会分配 PTY。
拥有 TTY/PTY 会改变您的 shell 初始化自身的方式。您的实际问题是您需要对远程系统上的 运行 psql 执行以下任何或所有操作:
- 将一个或多个目录添加到您的命令路径。
- 为您的环境添加一个或多个环境变量。
- 定义一个或多个别名。
您在 shell 启动文件(例如。bash_profile)中执行这些操作,并且它只发生在交互式会话中。当您远程使用 ssh 到 运行 psql 时,您的 shell 正在跳过允许 psql 到 运行.
的初始化有两种简单的方法可以解决此问题:
- 运行 带有“-t”或“-tt”选项的 ssh,这会导致 ssh 在远程系统上为 psql 分配一个 TTY。
- 更改远程系统上的 shell 启动文件以对非交互式会话执行必要的初始化。