python执行shell,报错:未找到命令

Python057

python执行shell,报错:未找到命令,第1张

 我打算用python来执行shell命令,实现sqoop导数据功能

 脚本如下:

   mysql_jdbc="jdbc:mysql://{0}:{1}/{2}?characterEncoding=utf8&autoReconnect=true"

    sqoop import "-Dorg.apache.sqoop.splitter.allow_text_splitter=true" \

    --connect $mysql_jdbc \

    --username {3} \

    --password {4} \

    --table {5} \

    --target-dir {7} \

    --delete-target-dir \

    --split-by clientid

然后报错:sqoop:未找到命令

然后我就测试:subprocess.run("java -version",shell=True)

也是报错:java:未找到命令

网上一顿百度,查了2天啊~~~~

1、检查/etc/profile环境变量设置没问题

2、linux机器上直接执行java -version也正常

3、linux机器上执行python3后,执行subprocess.run("java -version",shell=True)也正常

我就奇了怪了,还摆不平你这小娘子

后来突然想到之前项目里,先生效一下profile文件,试了一下,果然有效!!!

我的亲娘诶,绝望之际,解救了我~~~

至于为什么一定要这样,还是不解

正确脚本:

shell_str ="""

source /etc/profile

java -version

"""

subprocess.run(shell_str, shell=True)

这里用到subprocess内置库

subprocess.check_output() 与 subprocess.Popen() 一个是阻塞另一个是非阻塞

主要讲 subprocess.Popen()

p = Popen(shell_str, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE)

如果不加shell=True,shell_str要写成list或者tuple类型

p.wait()   如果0是正常,1是有异常

p.stdin.read()

p.stdout.read()

p.stderr.read()

stdin ,   stdout, stderr 分别是标准输出, 正常输出, 错误输出 

例子:

from subprocessimport *

p = Popen(shell_str.split(' '), stdin=PIPE, stdout=PIPE, stderr=PIPE)

p_statuscode = p.wait()

工具/原料

Python环境

方法/步骤

os.system("The command you want"). 这个调用相当直接,且是同步进行的,程序需要阻塞并等待返回。返回值是依赖于系统的,直接返回系统的调用返回值,所以windows和linux是不一样的

os.popen(command[,mode[,bufsize]]),

图中是一个例子.

可以看出,popen方法通过p.read()获取终端输出,而且popen需要关闭close().当执行成功时,close()不返回任何值,失败

时,close()返回系统返回值. 可见它获取返回值的方式和os.system不同。

使用commands模块,图中是一组例子。根据你需要的不同,commands模块有三个方法可供选择。getstatusoutput, getoutput, getstatus。

但是,如上三个方法都不是Python推荐的方法,而且在Python3中其中两个已经消失。Python文档中目前全力推荐第四个方法,subprocess! subprocess使用起来同样简单:

接调用命令,返回值即是系统返回。shell=True表示命令最终在shell中运行。Python文档中出于安全考虑,不建议使用

shell=True。建议使用Python库来代替shell命令,或使用pipe的一些功能做一些转义。官方的出发点是好的,不过真心麻烦了很多,

so.... 如果你更关注命令的终端输出,可以如下图这样操作, 同样很简单.