简体   繁体   English

Python代码将stdin和stdout重定向到Shell脚本

[英]Python code to redirect stdin and stdout to a shell script

I am trying to write a program that reads from a file and writes to a new file using the command line. 我正在尝试编写一个程序,该程序从文件读取并使用命令行将其写入新文件。 I am using the CommandLine class and using ArgParse to accept different args as well as the file names for input and output. 我正在使用CommandLine类,并使用ArgParse接受不同的args以及用于输入和输出的文件名。 I am trying to redirect stdin and stdout to these files. 我正在尝试将stdin和stdout重定向到这些文件。 However, I keep getting an error that I put at the bottom of the code below. 但是,我不断收到一个错误,该错误出现在下面的代码底部。 Am I inputting the arguments to the command line incorrectly, or is something else going on? 我是否在命令行中输入了错误的参数,还是发生了其他情况? All of my files are in the same folder. 我所有的文件都在同一个文件夹中。

class CommandLine() :
'''
Handle the command line, usage and help requests.

CommandLine uses argparse, now standard in 2.7 and beyond. 
it implements a standard command line argument parser with various argument options,
a standard usage and help, and an error termination mechanism do-usage_and_die.

attributes:
all arguments received from the commandline using .add_argument will be
avalable within the .args attribute of object instantiated from CommandLine.
For example, if myCommandLine is an object of the class, and requiredbool was
set as an option using add_argument, then myCommandLine.args.requiredbool will
name that option.

'''

def __init__(self, inOpts=None):
    '''
    CommandLine constructor.
    Implements a parser to interpret the command line argv string using argparse.
    '''

    import argparse
    self.parser = argparse.ArgumentParser(description = 'Program prolog - a brief description of what this thing does', 
                                         epilog = 'Program epilog - some other stuff you feel compelled to say', 
                                         add_help = True, #default is True 
                                         prefix_chars = '-', 
                                         usage = '%(prog)s [options] -option1[default] <input >output'
                                         )
    self.parser.add_argument('inFile', action = 'store', help='input file name')
    self.parser.add_argument('outFile', action = 'store', help='output file name')
    self.parser.add_argument('-lG', '--longestGene', action = 'store', nargs='?', const=True, default=False, help='longest Gene in an ORF')
    self.parser.add_argument('-mG', '--minGene', type=int, choices= (0, 100, 200, 300, 500, 1000), action = 'store', help='minimum Gene length')
    self.parser.add_argument('-s', '--start', action = 'append', nargs='?', help='start Codons') #allows multiple list options
    self.parser.add_argument('-st', '--stop', action = 'append', nargs='?', help='stop Codons') #allows multiple list options
    self.parser.add_argument('-v', '--version', action='version', version='%(prog)s 0.1')  
    if inOpts is None :
        self.args = self.parser.parse_args()
    else :
        self.args = self.parser.parse_args(inOpts)

C:\Users\Zach\Documents\UCSC\BME 160\Lab 5>python findORFsCmdLine.py --    minGene=3
00 --longestGene --start=ATG --stop=TAG --stop=TGA --stop=TAA <tass2.fa     >result.
txt
usage: findORFsCmdLine.py [options] -option1[default] <input >output
findORFsCmdLine.py: error: the following arguments are required: inFile,     outFile

The error tells you that you did not provide inFile and outFile . 该错误告诉您您未提供inFileoutFile This seems confusing because you did indeed provide <tass2.fa and >result.txt on the command line. 这似乎令人困惑,因为您确实在命令行上提供了<tass2.fa>result.txt

On the command line < and > have special meaning. 在命令行<>具有特殊含义。 <tass2.fa is handled by bash (or whichever shell you use) and it opens the file tass2.fa and sends the contents to your program over stdin . <tass2.fabash (或您使用的任何shell)处理,并打开文件tass2.fa并将内容通过stdin发送到您的程序。 It then removes that from the list of command line arguments because bash has already taken care of it. 然后,它将它从命令行参数列表中删除,因为bash已经处理了它。

A similar thing happens with >result.txt where any output from your file that normally goes to stdout such as print calls will be written to that file. >result.txt也会发生类似的情况,文件中的任何正常输出到stdout例如打印调用)都将写入该文件。 Again bash handles this so your program never gets the argument from the command line. bash再次处理此问题,因此您的程序永远不会从命令行获取参数。

To make sure the filenames go to your program you need to remove the < and > symbols. 为确保文件名进入程序,您需要删除<>符号。


In addition to that, the way you are call add_argument for inFile and outFile is not correct. 除此之外,你现在的样子通话add_argumentinFileoutFile是不正确的。 Using action='store' simply stores the value of the argument under the given name. 使用action='store'只是将参数的值存储在给定名称下。 This is the default action so doing that is redundant. 这是默认操作,因此这样做是多余的。

You need to tell add_argument that these are file types. 您需要告诉add_argument这些是文件类型。 Then you can use these as files and read and write as you desire. 然后,您可以将它们用作文件,并根据需要进行读写。

parser.add_argument('inFile', type=argparse.FileType('r'))
parser.add_argument('outFile', type=argparse.FileType('w'))

If you wish to allow these arguments to be optional and use stdin and stdout automatically if they do not supply a filename then you can do this: 如果您希望允许这些参数是可选的,并且在不提供文件名的情况下自动使用stdinstdout则可以执行以下操作:

parser.add_argument('inFile', type=argparse.FileType('r'),
    nargs='?', default=sys.stdin)
parser.add_argument('outFile', type=argparse.FileType('w'),
    nargs='?', default=sys.stdout)

You say you are writing a program that reads from a file and writes to a new file using the command line and go on to say that you are trying to redirect these files to stdin and stdout. 您说您正在编写一个程序,该程序可以从文件读取并使用命令行将其写入新文件,然后继续说您正在尝试将这些文件重定向到stdin和stdout。

If it is really your intention to redirect the input and output files using the shell with the > and < operators, then you do not need to call add_argument with outFile at all. 如果确实打算使用带有><运算符的shell重定向输入和输出文件,则根本不需要使用outFile调用add_argument Just let the shell handle it. 只需让外壳处理它即可。 Remove that line from your program and use print or similar to send your content to stdout and that file will be created. 从程序中删除该行,并使用print或类似方法将您的内容发送到stdout ,然后将创建该文件。 You will still need the call add_argument('inFile', ... . 您仍然需要调用add_argument('inFile', ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM