Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Shell脚本替换?_Python_Shell - Fatal编程技术网

Python Shell脚本替换?

Python Shell脚本替换?,python,shell,Python,Shell,我开始厌倦用shell脚本来执行自动化和在东西之间粘贴代码。我喜欢使用它进行快速而肮脏的数据处理,但即使对于生成进程并记住其进程id的简单三行代码,我也要花很长时间才能正确编程 对于每个命令,如果我没有显式检查返回代码,脚本可能会以退出代码0终止,即使我不想这样做。因此,每个shell命令后面都会跟着if语句,以查看程序是否正确终止 传递变量和编写健壮的命令行参数解析器很难(类似于Python中的optparse) 调试起来非常困难 我的大部分工作都使用python,但是,如果我开始使用子流

我开始厌倦用shell脚本来执行自动化和在东西之间粘贴代码。我喜欢使用它进行快速而肮脏的数据处理,但即使对于生成进程并记住其进程id的简单三行代码,我也要花很长时间才能正确编程

  • 对于每个命令,如果我没有显式检查返回代码,脚本可能会以退出代码0终止,即使我不想这样做。因此,每个shell命令后面都会跟着if语句,以查看程序是否正确终止
  • 传递变量和编写健壮的命令行参数解析器很难(类似于Python中的
    optparse
  • 调试起来非常困难
我的大部分工作都使用python,但是,如果我开始使用
子流程
模块,当我试图将python用于shell脚本编写时,它会觉得有点冗长


我在想这两者之间是否有一个很好的折衷点。比如,要么编写健壮的shell脚本而不太冗长,要么用更高级的语言(如Python)编写不太冗长的自动化脚本。

如果可以依赖正在运行的程序的退出状态,您是否考虑过使用“set-e”如果您可以依赖于正在运行的程序的退出状态?

您看过使用ruby吗。它有一些合成糖,使编写类似外壳的脚本变得容易。特别地,带反勾号引号的字符串的工作方式相同,
%x{..}
。事实上,在ruby中运行一个外部命令是不可能的。

您看过ruby的使用吗。它有一些合成糖,使编写类似外壳的脚本变得容易。特别地,带反勾号引号的字符串的工作方式相同,
%x{..}
。事实上,在ruby中需要运行外部命令。

问题是什么?我不认为很多人会认为Python是“冗长”的。它经常被提出来,以表明一种语言与Java相比是多么的冗长


顺便说一句,我认为Perl在语法和历史上都可以放在shell脚本和Python之间。

问题是什么?我不认为很多人会认为Python是“冗长”的。它经常被提出来,以表明一种语言与Java相比是多么的冗长


顺便说一句,我认为Perl在语法和历史上都可以放在shell脚本和Python之间。

以上所有好的建议,特别是
set-e
,这将是解决您的异议的一个很好的基本方法

捕获shell子进程错误的另一种方法是使用if语句,即

if true ; then
    printf "success\n"
else
    printf "failure\n"
fi
这将是这个想法最基本的说明

编辑

这里有一个更高级的例子,是从S.O.上的另一篇文章修改过来的

if ls /path/to/files*  /dev/null 2>&1 ; then
    echo "files do exist"
else
    echo "files do not exist"
fi
最后,可以使用
if cmd嵌入完整的管道命令;然后
语法,但管道中的最后一个调用是返回整个管道的真或假的值

编辑结束

不幸的是,有些Unix实用程序的返回代码并不完美(为此目的),但这是非常特定于平台的(可能我想到的是Sun4 sed,当然还有许多ftp客户端)。一个好的Linux发行版可能没有这个问题,但是在开始使用它时,您需要检查(或者记录)每个实用程序

对于反对意见#2,参数解析,我可以提供该问题的一个完整的辅助步骤,负面代码可能是其他人一开始很难理解的代码

不要依赖带有getargs和case语句的while循环来处理参数,而是查看在调用子流程之前添加环境变量是否有帮助,即

带标志的代码

 cat myProgram.sh
 #! /bin/bash
 set -e
 if ${testingMode:-false} ; then
     printf "${0##*/}:TestingMode:Starting:args=${@}"
 fi

 # more code
现在,您不需要嵌入任何内部处理来处理testingMode,而是将变量预先挂起到脚本命令行,并临时“打开”,即:

 testingMode=true ./myProgram.sh otherargs that makes sense as args
您可以将任意多的变量预先挂起到命令的前端,因此可以设想构建一个没有任何参数处理的脚本。有时有道理,有时没有道理。(顺便说一句,我是通过阅读Kernighan和Pike的《Unix编程环境》获得这项技术的。)

同样,如果你不得不担心在同一个组织的另一个工作岗位上传递这段代码,你可能需要参加一个关于使用这些很少使用的shell的培训课程

您的最后一个反对意见“难以调试”更难辩护,尤其是与不匹配的{}、()、“、和”相关的错误。有许多ksh调试器按照早期c语言调试器、dbx和gdbx的思路工作

祝你好运,当你发现一种编程语言可以“实现我的意思”时,请告诉我们:-)


我希望这能有所帮助。

以上所有好的建议,尤其是
set-e
,这将是解决您的异议的一个很好的基本方法

捕获shell子进程错误的另一种方法是使用if语句,即

if true ; then
    printf "success\n"
else
    printf "failure\n"
fi
这将是这个想法最基本的说明

编辑

这里有一个更高级的例子,是从S.O.上的另一篇文章修改过来的

if ls /path/to/files*  /dev/null 2>&1 ; then
    echo "files do exist"
else
    echo "files do not exist"
fi
最后,可以使用
if cmd;then
语法嵌入完整的管道命令,但管道中的最后一个调用是返回整个管道的真或假的命令

编辑结束

不幸的是,有些Unix实用程序的返回代码并不完美(为此目的),但这是非常特定于平台的(可能我想到的是Sun4 sed,当然还有许多ftp客户端)。可能是一个好的Linux发行版没有这个问题,但您需要检查(可能还有文档)当您开始使用它时,请查看每个实用程序

对于异议#2,参数解析,我可以提供一个comp