我一直试图将ls
的结果输入到我正在编写的C程序的命令行中(在Unix中)。我希望能够拥有文件的索引,因此我计划使用argv。这就是我认为它应该起作用的方式:
./foo &(ls ~/path)
它不起作用 - 将ls
的输出作为参数传递给命令的正确方法是什么?
答案 0 :(得分:4)
您的语法是位关闭...
./foo $(ls ~/path)
请注意,这会阻塞包含特定字符的文件。请使用数组来解决此问题。
pushd ~/path
files=(*)
popd
./foo "${files[@]}"
答案 1 :(得分:2)
您指定的符号有两个作用:
./foo &
在后台运行程序foo
(除了命令名之外没有其他参数)。然后:
(ls ~/path)
在子shell中运行ls
命令(在此上下文中,与在主shell中运行它相同)。问题是您打算(或需要)使用$
代替&
。
./foo $(ls ~/path)
这将运行命令ls ~/path
并捕获输出,该输出被拆分为单词(使用$IFS
变量中列出的分隔符)。然后根据需要将每个单词作为参数提供给命令./foo
。
然后我们可以辩论使用ls
这样的输出的智慧,但除非你有包含空格的文件名(标签,换行符等),否则你会没事的。
答案 2 :(得分:0)
您知道Unix工具如何接受glob模式,因此您可以执行cat *.txt
或rm ~/Pictures/Vacation*.jpg
,而无需管道/展开ls
?
这是你的shell免费提供程序的能力!
只需使用./foo ~/path/*
,argv[1]
将包含/home/you/path/fileone
,argv[2]
将包含/home/you/path/filetwo
,依此类推。
这些文件名可能是相对的或绝对的,但始终可以直接传递给open
/ fopen
/ execve
或您想要使用的任何功能。
如你所描述的那样使用ls
只会给你文件名的最后一部分没有目录,所以你不知道文件在哪里用它们做任何事情(虽然这是你想要的,只是使用basename(argv[1]))
。