使用 "at" (<<<) 通过 python 执行 bash-命令:语法错误,看到最后一个标记
Execute bash-command with "at" (<<<) via python: syntax error, last token seen
我在我的树莓派上使用无线电发送器来控制家里的一些照明设备。我正在尝试实施时间控制并且过去曾成功使用程序 "at"。
#!/usr/bin/python
import subprocess as sp
##### some code #####
sp.call(['at', varTime, '<<<', '\"sudo', './codesend', '111111\"'])
当我执行程序时,我收到
errmsg:
语法错误。最后看到的令牌:<
乱码时间
这个代码片段本身可以很好地处理每个命令(只要每个参数都来自字符串类型)。
需要这样调用"at":at 18:25 <<< "sudo ./codesend 111111"
将命令保存在队列中(在"atq"中可见),
因为sudo ./codesend 111111 | at 18:25
只是直接执行了命令,并在“/var/mail/user”中记下执行。
我的问题是,如何避免语法错误。
我在这个程序中使用了很多其他包,所以我必须继续使用 Python
我希望有人能解决这个问题或者能帮助找出我的错误。
非常感谢
前言:共享代码
将以下上下文视为此答案两个分支的一部分。
import subprocess as sp
try:
from shlex import quote # Python 3
except ImportError:
from pipes import quote # Python 2
# given the command you want to schedule, as an array...
cmd = ['sudo', './codesend', '111111']
# ...generate a safely shell-escaped string.
cmd_str = ' '.join(quote(x) for x in cmd))
解决方案 A:输入标准输入 Python
<<<
是 shell 语法。它对 at
没有任何意义,如果作为文字参数给出,at
完全正常并且预计会拒绝它。
不过您不需要调用 shell,您可以直接从本机 Python:
执行相同的操作
p = sp.Popen(['at', vartime], stdin=sp.PIPE)
p.communicate(cmd_str)
解决方案 B:显式调用 A Shell
此外,<<<
不是 /bin/sh
语法——它是 bash、ksh 和其他语法中的扩展;所以你不能仅仅通过添加 shell=True
标志(它使用 /bin/sh
并且因此只保证 POSIX-baseline 特征)来可靠地获得它。如果你想要它,你需要显式地调用一个 shell 的功能,像这样:
bash_script = '''
at "" <<<""
'''
sp.call(['bash', '-c', bash_script,
'_', # this is [=12=] for that script
vartime, # this is its
cmd_str, # this is its
])
无论哪种情况,请注意我们在从参数生成 shell 命令时使用 shlex.quote()
或 pipes.quote()
(适用于我们的 Python 版本)列表;这对于避免在我们的软件中创建 shell 注入漏洞至关重要。
我在我的树莓派上使用无线电发送器来控制家里的一些照明设备。我正在尝试实施时间控制并且过去曾成功使用程序 "at"。
#!/usr/bin/python
import subprocess as sp
##### some code #####
sp.call(['at', varTime, '<<<', '\"sudo', './codesend', '111111\"'])
当我执行程序时,我收到
errmsg: 语法错误。最后看到的令牌:<
乱码时间
这个代码片段本身可以很好地处理每个命令(只要每个参数都来自字符串类型)。
需要这样调用"at":at 18:25 <<< "sudo ./codesend 111111"
将命令保存在队列中(在"atq"中可见),
因为sudo ./codesend 111111 | at 18:25
只是直接执行了命令,并在“/var/mail/user”中记下执行。
我的问题是,如何避免语法错误。 我在这个程序中使用了很多其他包,所以我必须继续使用 Python
我希望有人能解决这个问题或者能帮助找出我的错误。 非常感谢
前言:共享代码
将以下上下文视为此答案两个分支的一部分。
import subprocess as sp
try:
from shlex import quote # Python 3
except ImportError:
from pipes import quote # Python 2
# given the command you want to schedule, as an array...
cmd = ['sudo', './codesend', '111111']
# ...generate a safely shell-escaped string.
cmd_str = ' '.join(quote(x) for x in cmd))
解决方案 A:输入标准输入 Python
<<<
是 shell 语法。它对 at
没有任何意义,如果作为文字参数给出,at
完全正常并且预计会拒绝它。
不过您不需要调用 shell,您可以直接从本机 Python:
执行相同的操作p = sp.Popen(['at', vartime], stdin=sp.PIPE)
p.communicate(cmd_str)
解决方案 B:显式调用 A Shell
此外,<<<
不是 /bin/sh
语法——它是 bash、ksh 和其他语法中的扩展;所以你不能仅仅通过添加 shell=True
标志(它使用 /bin/sh
并且因此只保证 POSIX-baseline 特征)来可靠地获得它。如果你想要它,你需要显式地调用一个 shell 的功能,像这样:
bash_script = '''
at "" <<<""
'''
sp.call(['bash', '-c', bash_script,
'_', # this is [=12=] for that script
vartime, # this is its
cmd_str, # this is its
])
无论哪种情况,请注意我们在从参数生成 shell 命令时使用 shlex.quote()
或 pipes.quote()
(适用于我们的 Python 版本)列表;这对于避免在我们的软件中创建 shell 注入漏洞至关重要。