【问题标题】:bash wrap a piped command with a python scriptbash 用 python 脚本包装一个管道命令
【发布时间】:2014-11-24 14:59:44
【问题描述】:

有没有办法创建一个 python 脚本来包装整个 bash 命令,包括管道。

例如,如果我有以下简单脚本

import sys
print sys.argv

并这样称呼它(来自 bash 或 ipython),我得到了预期的结果:

[pkerp@pendari trell]$ python test.py ls
['test.py', 'ls']

但是,如果我添加一个管道,脚本的输出会被重定向到管道接收器:

[pkerp@pendari trell]$ python test.py ls > out.txt

> out.txt 部分不在 sys.argv 中。我知道 shell 会自动处理这个输出,但我很好奇是否有办法强制 shell 忽略它并将其传递给被调用的进程。

这样做的目的是为外壳创建类似包装器的东西。我想定期运行命令,但跟踪每个命令(包括管道)的 strace 输出。理想情况下,我想保留所有 bash 功能,例如制表符补全、上下箭头和历史搜索,然后通过调用子进程来处理它的 python 脚本传递完成的命令。

这可能吗,还是我必须编写自己的 shell 才能做到这一点?

编辑

看来我问的问题与this question 完全相同。

【问题讨论】:

  • 术语说明:这不是管道,而是输出重定向。
  • 你是对的。对于那个很抱歉。这一点仍然适用。如果不是重定向而是管道,问题仍然存在。

标签: python bash shell strace


【解决方案1】:

您唯一能做的就是将整个 shell 命令作为字符串传递,然后让 Python 将其传递回 shell 执行。

$ python test.py "ls > out.txt"

test.py 内部,类似

subprocess.call("strace " + sys.argv[1], shell=True, executable="/bin/bash")

确保将整个字符串传递给 shell(特别是 bash)。

【讨论】:

  • 在包含我要运行的命令文本的.bashrc 中,我真的没有什么可以改变的吗?如果它被记录在历史文件中,它必须存储在某个地方。
  • 据我所知,bash 根本没有你想要的内省水平。
  • 嗯...你会碰巧知道另一个shell吗?
【解决方案2】:

嗯,我不太明白你想做什么。一般的方法是使用命令行选项为脚本提供所需的输出目标:python test.py ls --output=out.txt。顺便说一句,strace 写入 stderr。如果您想保存所有内容,可以使用 strace python test.py > out 2> err 捕获所有内容...

编辑:如果您的脚本也写入 stderr,您可以使用 strace -o strace_out python test.py > script_out 2> script_err

Edit2:好的,我更明白你想要什么。我的建议是:写一个 bash 助手:

function process_and_evaluate()
{

  strace -o /tmp/output/strace_output "$@"

  /path/to/script.py /tmp/output/strace_output
}

把它放在像~/helper.sh 这样的文件中。然后打开一个 bash,使用 . ~/helper.sh 获取它。 现在你可以像这样运行它:process_and_evaluate ls -lA

编辑3: 要捕获输出/错误,您可以像这样扩展宏:

function process_and_evaluate()
{
  out=$1
  err=$2

  shift 2

  strace -o /tmp/output/strace_output "$@" > "$out" 2> "$err"

  /path/to/script.py /tmp/output/strace_output
}

您必须使用(不太明显)process_and_evaluate out.txt err.txt ls -lA。 这是我能想到的最好的......

【讨论】:

  • 对,想象一下我有一个命令ls -l > ls_output.txt 2> ls_error.txt。我想像往常一样从shell运行这个命令,但是在我按下回车键并执行命令之间,我想调用一个python脚本,它将命令包装在strace调用中,然后处理输出。
  • 另外,您的示例不会捕获重定向生成的文件访问。必须运行`strace -o bash -c "ls > ls_out 2> ls_err"',但这不是重点。我希望它由 python 脚本处理的原因是为每个命令处理 strace 的输出。
  • 助手没有捕获重定向:(
【解决方案3】:

至少在您的简单示例中,您可以只运行 python 脚本作为 echo 的参数,例如

$ echo $(python test.py ls) > test.txt
$ more test.txt
['test.py','ls']

用美元符号括在括号中的命令首先执行内容,然后将输出作为参数传递给 echo。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-24
    • 1970-01-01
    相关资源
    最近更新 更多