【问题标题】:Python's popen, bash scripts and CentOSPython popen、bash 脚本和 CentOS
【发布时间】:2014-10-01 18:33:53
【问题描述】:

我正在从 Apache 运行一个 Django 服务器,它通过 subprocess.popen 启动一个 Bash 脚本 (/usr/bin/tf)。我的问题是我无法从 Bash 脚本访问特定目录它看起来真的不像是权限问题。通过在 Bash 脚本中运行 whoami 确认的执行用户是 apache

注意:/usr/bin/tf 是通过 Bash 执行的 Bash 脚本。 /usr/lib/tfs 是包含 Bash 脚本依赖项的目录。

Python 公开调用:

subprocess.Popen(['/bin/bash', '/usr/bin/tf'],
                 env=env,
                 stderr=subprocess.PIPE,
                 stdout=subprocess.PIPE,
                 close_fds=(os.name != 'nt'))

我也尝试过使用 shell=True(只是想看看这是否能解决问题)。在所有情况下,除了 shell=True,我什至无法从 ls / 获得有效列表。使用 shell=True 我可以看到 ls / 一直到 ls /usr/bin;但是,我仍然无法访问 /usr/lib/tfs/lib 中 tf 的 libs 文件夹。我可以看到 /usr/lib 中的内容。通过“无法访问”,我的真正意思是“ls”调用返回一个空行而不是文件/目录列表。

根据this page 的建议,我正在通过 /bin/bash 执行 Bash 脚本。

我已经尝试了一些方法来确保权限至少应该有效:

chown -R apache:apache /usr/lib/tfs
chmod -R 7777 /usr/lib/tfs (obviously bad but should have worked...)

chown -R --reference=/usr/lib /usr/lib/tfs
chmod -R --reference=/usr/lib /usr/lib/tfs

简而言之,当在 Python 中使用 popen 启动时,是否存在限制从进程访问文件的东西?

更新 2 执行“ls -la /usr/lib”显示了一些很奇怪的东西,所有的?都是/usr/lib/tfs的目录权限。

d??????????  ? ?    ?         ?            ? tfs
drwxr-xr-x.  3 root root   4096 Jul  1 17:08 udev
drwxr-xr-x. 15 root root   4096 Jul 31 14:09 vmware-tools
drwxr-xr-x.  4 root root   4096 Jul  7 04:26 x86_64-redhat-linux5E
drwxr-xr-x.  2 root root   4096 Jul  1 17:10 yum-plugins

【问题讨论】:

  • “无法访问”到底是什么意思?大概/usr/bin/tf 在您运行它时不起作用但是以什么方式?您是否有理由为此运行 tfbash 而不是直接运行它?这是以什么用户身份运行的?该用户可以手动运行tf 吗?使用['/bin/bash', '/usr/bin/tf'] 仅在tf 是shell 脚本而不是二进制文件时才有效,因为它试图运行/bin/bash /usr/bin/tf,你自己试试看吧。
  • tf 是一个 Bash 脚本,我应该更清楚。调查指出,popen 模拟了一个 shell,但缺乏通用的 shell 功能,所以大多数人会通过 bash 执行一个 bash 脚本。 tf 确实执行正确,但在脚本中我无法访问目录。执行用户是 apache(因为它是由通过 apache 运行的 Django 发起的)。直接执行 tf,而不是通过 bash,工作方式类似,但无法访问一些常用命令(即 cd)。我不需要那个,我最初尝试不使用 Bash,但仍然得到相同的结果。
  • 您仍然没有解释“无法访问目录”。这到底是什么意思? 究竟是什么失败了,有什么错误吗?
  • 在 bash 中,如果我执行“ls /usr/lib/tfs”,我会得到一个空行。没有错误,只是一个空行。我确实得到了带有“ls /”甚至“ls /usr/lib”的文件/目录列表,而不是 tfs。请注意,只有当我使用 shell=True 时才会出现这种情况。如果我不使用 shell=True,那么除了当前目录(即“ls”而不是“ls .”,它总是给出一个空行)之外,我总是从“ls any”中得到空行。
  • 你是如何从“[w]in the bash”执行这些命令的? ['/bin/bash', 'ls /usr/lib/tfs']?因为那不是你想的那样。检查该子进程调用的标准错误,看看你得到了什么。

标签: python apache bash popen


【解决方案1】:

不妨试试:

#!/usr/local/cpython-3.4/bin/python

# pylint: disable=superfluous-parens
# superfluous-parens: Parentheses are good for clarity and portability

'''Start tf'''

# Runs on 2.[4567] and 3.[01234]

import os
import subprocess


def main():
    '''Main function'''
    stuff = subprocess.Popen(
        ['/bin/bash', '/usr/local/bin/tf'],
        env=os.environ,
        stderr=subprocess.PIPE,
        stdout=subprocess.PIPE,
        close_fds=(os.name != 'nt'),
    )
    stdout, dummy = stuff.communicate()
    os.write(1, stdout)

main()

HTH

顺便说一句,不要尝试运行“ls -l”。除非您给出 shell=True,否则请改用 ['ls', '-l']。

【讨论】:

    【解决方案2】:

    目录权限虽然在以 root 或 apache 身份登录时看起来很好(使用 su apache -s /bin/bash),但被执行的 bash 脚本搞砸了。我怀疑这些目录来自 Windows 机器,并且参与了无效的权限设置。

    修复实际上只是复制目标目录并使用副本,删除旧目录。

    mv /usr/lib/tf /usr/lib/tfold
    cp /usr/lib/tfold /usr/lib/tf
    rm -rf /usr/lib/tfold
    

    【讨论】:

      猜你喜欢
      • 2014-07-28
      • 2012-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-15
      • 2016-01-28
      • 1970-01-01
      • 2017-01-11
      相关资源
      最近更新 更多