Python中shell函数的使用

Python中shell函数的使用,python,bash,shell,environment-variables,Python,Bash,Shell,Environment Variables,我在Win 10下使用Msys2便携式,但我想这同样适用于许多其他Linuxe/Bash 在shell提示符下运行python脚本时,如何知道它的shell函数和相应参数? 我有一个bashshell,在这里我定义了一个shell函数myfun $ type myfun myfun is a function myfun () { ... (this contains a call to a shell script, that is found in a dire

我在Win 10下使用Msys2便携式,但我想这同样适用于许多其他Linuxe/Bash

在shell提示符下运行python脚本时,如何知道它的shell函数和相应参数?

我有一个bashshell,在这里我定义了一个shell函数
myfun

$ type myfun
myfun is a function
myfun ()
{
    ...
    (this contains a call to a shell script, 
      that is found in a directory which is part of $PATH)
}
可能需要参数,例如,
$myfun d
, 我有一个python脚本
myscript.py
,它在从bashshell运行时运行良好。 现在,我想在
myscript.py
中添加行,以便从其中执行
myfun
,并使其也可以使用(与以前相同)



编辑#1: 收到答案后,我用
export-f myfun
导出了函数。 然后,我在脚本中尝试了6种备选方案:(使用/不使用
bash-c
),并结合(
subprocess.run
os.system
os.popen

我在这里列出了6种组合中的每一种,添加到
myscript.py
的行,以及执行
python3 myscript.py
时获得的输出:

  • 增加
  • 获得(与之前相同)

  • 增加
  • 取得了预期的效果

  • 增加
  • 获得 没有错误,但显然什么也没做(非常奇怪,必须进一步检查发生了什么)

  • 增加
  • 获得: 执行函数,但忽略函数参数

  • 增加
  • 取得了预期的效果

  • 增加
  • 获得 没有错误,但显然什么也没做(非常奇怪,必须进一步检查发生了什么)



    原始问题和状态

    我尝试了几个选项,但都失败了(详见下文)。 一方面,似乎即使从bashshell执行
    myscript.py
    ,它也会启动一个单独的
    sh
    shell,而不知道我的shell函数。 另一方面,如果将
    print(os.environ)
    添加到
    myscript.py
    ,我会看到在
    ~/.bashrc
    中设置的环境变量,因此脚本至少正确地从shell继承了这些变量


    我在这里列出了添加到
    myscript.py
    的行,以及执行
    python3 myscript.py
    时获得的输出:

  • 增加
  • 获得

    sh: myfun: command not found
    
    /bin/sh: myfun: command not found
    
  • 增加
  • 获得

    sh: myfun: command not found
    
    /bin/sh: myfun: command not found
    
  • 增加
  • 获得

    sh: myfun: command not found
    
    /bin/sh: myfun: command not found
    

    默认情况下,环境是私有的。导出函数并确保在系统调用中运行
    bash
    myfun
    是一个bash函数,您必须运行
    bash
    才能运行它的函数

    $ myfun() { echo 1; }
    $ export -f myfun
    $ python <<<'import os; os.system("bash -c myfun")'
    1
    $ python <<<'import subprocess as s; s.run(["bash", "-c", "myfun"])'
    1
    $ python <<<'import os; os.popen("bash -c \'myfun"); # ... '
    

    默认情况下,环境是私有的。导出函数并确保在系统调用中运行
    bash
    myfun
    是一个bash函数,您必须运行
    bash
    才能运行它的函数

    $ myfun() { echo 1; }
    $ export -f myfun
    $ python <<<'import os; os.system("bash -c myfun")'
    1
    $ python <<<'import subprocess as s; s.run(["bash", "-c", "myfun"])'
    1
    $ python <<<'import os; os.popen("bash -c \'myfun"); # ... '
    

    导出
    myfun
    是我错过的必要步骤。修正这个问题,
    bash-c
    可能不需要(取决于我执行
    myfun
    时使用的内容)。即使在添加
    bash-c
    时,对于执行
    myfun
    的某些方法,我仍然无法使其工作。注意:
    myfun
    接受参数,这使得事情变得有点棘手。我之前没有澄清这一点,因为我落后于这个问题一步。我在编辑的OP中对此进行了更新。注意:根据我获得的结果,我猜您演示事物如何工作的方式可能存在差距,这取决于我执行函数时使用的内容,最可能取决于当前用户在/etc/passwd中存储为默认shell的内容<代码>注意:我使用的函数需要参数,这让事情变得有点棘手。因此,这是学习如何正确引用bash参数的好机会。提示:
    printf“%q”
    在bash中可能会有所帮助(我认为python中有引用shell参数的功能)。
    我想在演示如何工作的方式之间可能存在差距。
    好吧,唯一的区别是在解释单引号字符-它是结束引用。但是在脚本中复制没有单引号的命令后,它们的工作方式是相同的。用一些通过单个参数的示例编辑了答案。
    d
    。你的三个版本也都对我有用(不能两次投票!!)。我无法使
    os.popen
    工作。
    python导出
    myfun
    是我错过的必要步骤。修正这个问题,
    bash-c
    可能不需要(取决于我执行
    myfun
    时使用的内容)。即使在添加
    bash-c
    时,对于执行
    myfun
    的某些方法,我仍然无法使其工作。注意:
    myfun
    接受参数,这使得事情变得有点棘手。我之前没有澄清这一点,因为我落后于这个问题一步。我在编辑的OP中对此进行了更新。注意:根据我获得的结果,我猜您演示事物如何工作的方式可能存在差距,这取决于我执行函数时使用的内容,最可能取决于当前用户在/etc/passwd中存储为默认shell的内容<代码>注意:我使用的函数需要参数,这让事情变得有点棘手。
    因此,这是学习如何正确引用bash参数的好机会。提示:
    printf“%q”
    在bash中可能会有所帮助(我认为python中有引用shell参数的功能)。
    我想在演示如何工作的方式之间可能存在差距。
    好吧,唯一的区别是在解释单引号字符-它是结束引用。但是在脚本中复制没有单引号的命令后,它们的工作方式是相同的。用一些通过单个参数的示例编辑了答案。
    d
    。你的三个版本也都对我有用(不能两次投票!!)。我无法使
    os.popen
    工作。
    python
    
    import subprocess
    subprocess.run(["myfun", "d"])
    
    Traceback (most recent call last):
    ...
    FileNotFoundError: [Errno 2] No such file or directory: 'myfun'
    
    import os
    os.system("myfun d")
    
    sh: myfun: command not found
    
    import os
    stream = os.popen("myfun d")
    
    /bin/sh: myfun: command not found
    
    $ myfun() { echo 1; }
    $ export -f myfun
    $ python <<<'import os; os.system("bash -c myfun")'
    1
    $ python <<<'import subprocess as s; s.run(["bash", "-c", "myfun"])'
    1
    $ python <<<'import os; os.popen("bash -c \'myfun"); # ... '
    
    $ myfun() { echo "\$#=$#" "\$*=$*"; }
    $ export -f myfun
    $ python <<<'import os; os.system("bash -c \"myfun \\\"\$@\\\"\" -- d")'
    $#=1 $*=d
    
    # or way better use subprocess
    $ python <<<'import subprocess as s; s.run(["bash", "-c", "myfun \"$@\"", "--", "d"])'
    $#=1 $*=d
    
    # but still can do the more unsafe version
    # that will undergo word expansion or you have to properly escape the strings
    # (and double-double escape for `os.systems`)
    $ python <<<'import subprocess as s; s.run(["bash", "-c", "myfun d"])'
    $#=1 $*=d