Python raw_input 故障和 returns -bash:第 1 行:<INPUT>:找不到命令
Python raw_input malfunctions and returns -bash: line 1: <INPUT>: command not found
我编写了一个脚本来建立 SSH 隧道并通过该隧道连接到数据库。
极简坚果shell(省略明显参数和多余逻辑):
sshTunnelCmd = "ssh -N -p %s -L %s:127.0.0.1:%s -i %s %s@%s" % (
sshport, localport, remoteport, identityfile, user, server
)
args = shlex.split(sshTunnelCmd)
tunnel = subprocess.Popen(args)
time.sleep(2)
con = MySQLdb.connect(host="127.0.0.1", port=localport, user=user, passwd=pw, db=db)
## DO THE STUFF ##
con.close()
tunnel.kill()
shell-等效命令在下面,我已经测试了命令和脚本在"clean client"条件下的工作,即在重启。
ssh -N -p 22 -L 5000:127.0.0.1:3306 user@server
mysql --port 5000 -h 127.0.0.1 -u dbuser -p
SSH 登录使用密钥,在 ~/.ssh/config 服务器配置为
Host server
Hostname F.Q.D.N
Port 22
User user
ControlMaster auto
ControlPath ~/.ssh/master-%r@%h:%p
ControlPersist 600
IdentityFile ~/.ssh/id_rsa
在## DO THE STUFF ## 部分中,有代码尝试以普通用户身份连接到数据库。如果出现异常,它会要求手动输入 root 凭据,创建普通用户并继续执行这些操作(普通查询,全部手动测试并在干净的客户端条件下在 python 代码中工作)。
ruz = raw_input('root user? ')
print (ruz)
rup = raw_input('root password? ')
print (rup)
print ("Root connecting to database.")
try:
cxroot = MySQLdb.connect(host=host, port=port, user=ruz, passwd=rup)
cur = cxroot.cursor()
except MySQLdb.Error, e:
print ("Root failed, sorry.")
print "Error %d: %s" % (e.args[0],e.args[1])
print ("GAME OVER.")
return -1
在干净的客户端下,第一次和一些后续执行工作正常,包括当我尝试测试脚本的健壮性和删除用户服务器端时。然而,在某些时候,它以一种奇怪的方式挂在上面代码块 第二个 raw_input 之后 。输出:
root user? root
root
root password? s3cReTsTr1n9
-bash: line 1: s3cReTsTr1n9: command not found
此时我唯一能做的就是终止进程或按 CTRL+C,然后是以下回溯:
^CTraceback (most recent call last):
File "./initdb.py", line 571, in <module>
main()
File "./initdb.py", line 526, in main
connection = connectDB ('127.0.0.1', localport, dbuser, dbpw, db)
File "./initdb.py", line 128, in connectDB
rup = raw_input('root password? ')
KeyboardInterrupt
我注意到的另一个意想不到的症状是键盘输入到终端window(我是运行这个在bash终端内Xubuntu 14.04LTS) 变得虚假地没有响应,所以我必须关闭终端选项卡并打开一个新选项卡。这会清除键盘输入,但不会清除脚本行为。
我曾尝试寻找解决方案,但通常的搜索引擎对我的情况没有帮助,可能是因为我不完全了解发生了什么。我怀疑键盘输入以某种方式重定向到一个进程,可能是隧道子进程,但我无法解释为什么第一个 raw_input 按预期工作而第二个没有。
我也对我创建隧道的方式感到不舒服,因此欢迎任何关于更强大的隧道创建的建议。具体来说,我希望对隧道的创建有更细粒度的控制,而不是等待任意两秒钟来建立隧道,因为我没有来自该子进程的反馈。
感谢您分享您的时间和专业知识。
您可以随意配置服务器吗?
然后尝试 vpn 连接而不是 ssh 端口转发。这将更容易重新连接而不影响您的应用程序,因此隧道可能更稳定。
对于 raw_input 问题,我不明白为什么会这样,但也许 shell 中的 ssh 命令干扰了您的终端?如果您真的想集成 ssh 隧道,您可能需要查看一些 python 处理 ssh 的模块。
我的回答分为两部分:我将如何进行诊断,以及我将如何进行诊断。
首先,我建议使用失败的提示作为探索的机会。
您可以在此处采用两种方法:
- 只需输入
hostname
(或其他任何内容)即可找出 运行 的位置
- 输入
bash
,或者如果远程端有 X 服务器,请将 -X
添加到您的 ssh 命令,然后键入终端程序(xterm
、gnome-terminal
等).在你的新 shell 中,你可以四处看看发生了什么。
如果您在客户端确定它是 运行,您可以使用 strace
:
来诊断它
strace -f -o blah.log yourscript.py
... 您可以在其中输入易于搜索的密码字符串,然后在 blah.log
中搜索该密码。由于 -f
标志,它将打印试图执行它的进程的 PID;从那里回溯,您可能会发现 PID 是从另一个 PID 的分支开始的。该 PID 是试图执行它的原因,因此您应该能够从那里进行调查。
至于我会怎么做:我对 python 还是很陌生,所以我倾向于使用 perl 或 expect。在 perl 路径下,您可能会看到:
- Net::SSH::Tunnel;这可能是我考虑使用的第一个。
- 使用 open 或 open3 然后做一些像 hacky 这样的事情:
- 等待进程上的标准输出有可用的文本;为此,您必须摆脱
-N
,并且您将受到远程自动注销的支配。
- 对ssh-check-if-a-tunnel-is-alive
的各种回应之一
- Net::SSH::Expect (eg this post,虽然我没有看他的实现,所以你必须自己做出选择)。这个或 "real" expect 可能有点矫枉过正,但我相信你可以找到一种方法。
虽然 ruby 有一个 gem 像 perl 的 Net::SSH::Tunnel,但我没有看到 python 的点。 This question and this one both discuss it and they seem to indicate you're limited to either starting it as a sub-process or using paramiko.
-bash:第 1 行:s3cReTsTr1n9:未找到命令
即使我刚刚接受 raw_input() / input(),我也遇到了与 -bash command not found 相同的错误。我在 2.7 和 3.7 版本都试过了。
我在同一个 mac machine 上尝试 运行 客户端服务器程序。我有两个文件 server.py 和 client.py。每次在终端中,我首先在后台 运行 server.py 然后 运行 client.py。
1 号航站楼:python server.py &
2号航站楼:pythonclient.py
每次我收到错误“-bash:xxxx:找不到命令”。 xxxx 这里是我提供的任何输入。
最后,在花了 5 个小时之后,我在后台停止了 运行ning server.py。
1 号航站楼:pythonserver.py
2号航站楼:pythonclient.py
中提琴奏效了。 raw_input 并且输入没有再给我这个错误。
我不确定这是否有帮助。但这是我在互联网上找到的唯一 post 与我的问题完全相同的问题。并认为这可能会有所帮助。
我编写了一个脚本来建立 SSH 隧道并通过该隧道连接到数据库。
极简坚果shell(省略明显参数和多余逻辑):
sshTunnelCmd = "ssh -N -p %s -L %s:127.0.0.1:%s -i %s %s@%s" % (
sshport, localport, remoteport, identityfile, user, server
)
args = shlex.split(sshTunnelCmd)
tunnel = subprocess.Popen(args)
time.sleep(2)
con = MySQLdb.connect(host="127.0.0.1", port=localport, user=user, passwd=pw, db=db)
## DO THE STUFF ##
con.close()
tunnel.kill()
shell-等效命令在下面,我已经测试了命令和脚本在"clean client"条件下的工作,即在重启。
ssh -N -p 22 -L 5000:127.0.0.1:3306 user@server
mysql --port 5000 -h 127.0.0.1 -u dbuser -p
SSH 登录使用密钥,在 ~/.ssh/config 服务器配置为
Host server
Hostname F.Q.D.N
Port 22
User user
ControlMaster auto
ControlPath ~/.ssh/master-%r@%h:%p
ControlPersist 600
IdentityFile ~/.ssh/id_rsa
在## DO THE STUFF ## 部分中,有代码尝试以普通用户身份连接到数据库。如果出现异常,它会要求手动输入 root 凭据,创建普通用户并继续执行这些操作(普通查询,全部手动测试并在干净的客户端条件下在 python 代码中工作)。
ruz = raw_input('root user? ')
print (ruz)
rup = raw_input('root password? ')
print (rup)
print ("Root connecting to database.")
try:
cxroot = MySQLdb.connect(host=host, port=port, user=ruz, passwd=rup)
cur = cxroot.cursor()
except MySQLdb.Error, e:
print ("Root failed, sorry.")
print "Error %d: %s" % (e.args[0],e.args[1])
print ("GAME OVER.")
return -1
在干净的客户端下,第一次和一些后续执行工作正常,包括当我尝试测试脚本的健壮性和删除用户服务器端时。然而,在某些时候,它以一种奇怪的方式挂在上面代码块 第二个 raw_input 之后 。输出:
root user? root
root
root password? s3cReTsTr1n9
-bash: line 1: s3cReTsTr1n9: command not found
此时我唯一能做的就是终止进程或按 CTRL+C,然后是以下回溯:
^CTraceback (most recent call last):
File "./initdb.py", line 571, in <module>
main()
File "./initdb.py", line 526, in main
connection = connectDB ('127.0.0.1', localport, dbuser, dbpw, db)
File "./initdb.py", line 128, in connectDB
rup = raw_input('root password? ')
KeyboardInterrupt
我注意到的另一个意想不到的症状是键盘输入到终端window(我是运行这个在bash终端内Xubuntu 14.04LTS) 变得虚假地没有响应,所以我必须关闭终端选项卡并打开一个新选项卡。这会清除键盘输入,但不会清除脚本行为。
我曾尝试寻找解决方案,但通常的搜索引擎对我的情况没有帮助,可能是因为我不完全了解发生了什么。我怀疑键盘输入以某种方式重定向到一个进程,可能是隧道子进程,但我无法解释为什么第一个 raw_input 按预期工作而第二个没有。
我也对我创建隧道的方式感到不舒服,因此欢迎任何关于更强大的隧道创建的建议。具体来说,我希望对隧道的创建有更细粒度的控制,而不是等待任意两秒钟来建立隧道,因为我没有来自该子进程的反馈。
感谢您分享您的时间和专业知识。
您可以随意配置服务器吗? 然后尝试 vpn 连接而不是 ssh 端口转发。这将更容易重新连接而不影响您的应用程序,因此隧道可能更稳定。
对于 raw_input 问题,我不明白为什么会这样,但也许 shell 中的 ssh 命令干扰了您的终端?如果您真的想集成 ssh 隧道,您可能需要查看一些 python 处理 ssh 的模块。
我的回答分为两部分:我将如何进行诊断,以及我将如何进行诊断。
首先,我建议使用失败的提示作为探索的机会。
您可以在此处采用两种方法:
- 只需输入
hostname
(或其他任何内容)即可找出 运行 的位置
- 输入
bash
,或者如果远程端有 X 服务器,请将-X
添加到您的 ssh 命令,然后键入终端程序(xterm
、gnome-terminal
等).在你的新 shell 中,你可以四处看看发生了什么。
如果您在客户端确定它是 运行,您可以使用 strace
:
strace -f -o blah.log yourscript.py
... 您可以在其中输入易于搜索的密码字符串,然后在 blah.log
中搜索该密码。由于 -f
标志,它将打印试图执行它的进程的 PID;从那里回溯,您可能会发现 PID 是从另一个 PID 的分支开始的。该 PID 是试图执行它的原因,因此您应该能够从那里进行调查。
至于我会怎么做:我对 python 还是很陌生,所以我倾向于使用 perl 或 expect。在 perl 路径下,您可能会看到:
- Net::SSH::Tunnel;这可能是我考虑使用的第一个。
- 使用 open 或 open3 然后做一些像 hacky 这样的事情:
- 等待进程上的标准输出有可用的文本;为此,您必须摆脱
-N
,并且您将受到远程自动注销的支配。 - 对ssh-check-if-a-tunnel-is-alive 的各种回应之一
- 等待进程上的标准输出有可用的文本;为此,您必须摆脱
- Net::SSH::Expect (eg this post,虽然我没有看他的实现,所以你必须自己做出选择)。这个或 "real" expect 可能有点矫枉过正,但我相信你可以找到一种方法。
虽然 ruby 有一个 gem 像 perl 的 Net::SSH::Tunnel,但我没有看到 python 的点。 This question and this one both discuss it and they seem to indicate you're limited to either starting it as a sub-process or using paramiko.
-bash:第 1 行:s3cReTsTr1n9:未找到命令
即使我刚刚接受 raw_input() / input(),我也遇到了与 -bash command not found 相同的错误。我在 2.7 和 3.7 版本都试过了。
我在同一个 mac machine 上尝试 运行 客户端服务器程序。我有两个文件 server.py 和 client.py。每次在终端中,我首先在后台 运行 server.py 然后 运行 client.py。
1 号航站楼:python server.py &
2号航站楼:pythonclient.py
每次我收到错误“-bash:xxxx:找不到命令”。 xxxx 这里是我提供的任何输入。
最后,在花了 5 个小时之后,我在后台停止了 运行ning server.py。
1 号航站楼:pythonserver.py
2号航站楼:pythonclient.py
中提琴奏效了。 raw_input 并且输入没有再给我这个错误。
我不确定这是否有帮助。但这是我在互联网上找到的唯一 post 与我的问题完全相同的问题。并认为这可能会有所帮助。