Python标准输入文件名

8

我想获取从命令行传递的文件名。例如:

python3 ritwc.py < DarkAndStormyNight.txt

我想要获取的是 DarkAndStormyNight.txt 文件名。

当我尝试使用 fileinput.filename() 或 sys.stdin 时,返回的结果都是一样的。这是否可能?我不想使用返回当前脚本名称的 sys.argv[0]。

谢谢!

4个回答

6

通常情况下,无法以跨平台的方式获取文件名。其他答案涵盖了一些明智的替代方案,例如通过命令行传递名称。

在Linux和某些相关系统上,您可以通过以下技巧获取文件名:

import os
print(os.readlink('/proc/self/fd/0'))

/proc/ 是 Linux 上的一个特殊文件系统,提供有关机器上进程的信息。 self 表示当前运行的进程(打开文件的那个进程)。fd 是一个目录,其中包含进程中每个打开文件描述符的符号链接。0 是 stdin 的文件描述符编号。


你好,nneonneo,你知道为什么我的Ubuntu确实有路径/proc/self/fd/0,但是当我执行 ./test.py < test.txt 时,出现了错误No such file or directory: '/proc/self/fd/0'吗?谢谢。 - user2558887
@Mr.Pei,你可以尝试用os.getpid()返回的进程PID替换'self'。另一方面,可能是Ubuntu没有挂载/proc文件系统,或者您没有读取它的权限。 - Carlos

2
您可以使用ArgumentParser,它自动提供了命令行参数的界面,甚至还提供帮助等功能。
from argparse import ArgumentParser
parser = ArgumentParser()                                                                 
parser.add_argument('fname', metavar='FILE', help='file to process')
args = parser.parse_args()

with open(args.fname) as f:
    #do stuff with f

现在你可以调用python2 ritwc.py DarkAndStormyNight.txt。如果你调用没有参数的python3 ritwc.py,它会报错,说它期望有FILE参数。现在你也可以调用python3 ritwc.py -h,它会解释需要一个要处理的file
附注:这里有一个很好的介绍如何使用它的链接:http://docs.python.org/3.3/howto/argparse.html

1
事实上,当 stdin 从控制台重定向时,Python 似乎无法看到该文件名,因此您有另一种选择:
以如下方式调用您的程序:
python3 ritwc.py -i your_file.txt

然后在Python内部添加以下代码以重定向stdin,这样您就可以通过变量“filename_in”访问文件名:

import sys 

flag=0
for arg in sys.argv:
    if flag:
        filename_in = arg
        break
    if arg=="-i":
        flag=1
sys.stdin = open(filename_in, 'r')

#the rest of your code...

If now you use the command:

print(sys.stdin.name)

你可以获得文件名;但是,如果你在将stdin重定向后执行相同的打印命令,则会得到结果:<stdin>,这表明Python无法以这种方式看到文件名。

0

我认为这是不可能的。就你的 Python 脚本而言,它正在写入标准输出。你在 shell 中捕获标准输出并将其写入文件的事实与 Python 脚本无关。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接