我需要运行一个系统命令,该命令将转到一个目录并删除不包括文件的子目录(如果存在)。我编写了以下命令来执行此操作:
system("cd /home/faizan/test/cache ; for i in *\; do if [ -d \"$i\" ]\; then echo \$i fi done");
上面的命令不断抛出语法错误。我尝试了多种组合,但仍然不清楚这应该如何进行。请建议。
好吧,您的命令行确实包含语法错误。试试这个:
system("cd /home/faizan/test/cache ; for i in *; do if [ -d \"\$i\" ]; then echo \$i; fi; done");
或者更好的是,首先只遍历目录;
system("for i in /home/faizan/test/cache/*/.; do echo \$i; done");
或者更好的是,不要循环:
system("echo /home/faizan/test/cache/*/.");
(我想你会想要rmdir
而不是echo
一旦它被正确调试。)
或者更好的是,全部在 Perl 中完成。这里没有什么需要system()
.
由于问题标题代表system
命令,这将直接回答,但使用 bash 的示例命令仅包含仅在 perl 中更简单的内容(使用opendir
和-d
在 perl 中查看其他答案)。
如果您想使用system
(而不是open $cmdHandle,"bash -c ... |"
),执行命令(如system
or )的首选语法exec
是让perl
解析命令行。
试试这个(就像你已经做过的那样):
perl -e 'system("bash -c \"echo hello world\"")'
hello world
perl -e 'system "bash -c \"echo hello world\"";'
hello world
现在更好,相同但perl
确保命令行解析,试试这个:
perl -e 'system "bash","-c","echo hello world";'
hello world
显然有3个system
命令参数:
或更多:
perl -e 'system "bash","-c","echo hello world;date +\"Now it is %T\";";'
hello world
Now it is 11:43:44
正如您在最后一个目的中看到的那样,命令行的bash脚本部分没有双引号。
**注意:在命令行上,使用perl -e '...'
or perl -e "..."
,使用引号和双引号有点重。在脚本中,您可以混合它们:
system 'bash','-c','for ((i=10;i--;));do printf "Number: %2d\n" $i;done';
甚至:
system 'bash','-c','for ((i=10;i--;));do'."\n".
'printf "Number: %2d\n" $i'."\n".
'done';
使用点.
来连接(脚本部分)字符串的一部分,总是有 3 个参数。
您仍然最好先将其作为 bash 命令尝试。正确格式化可以更清楚地表明您缺少语句终止符:
for i in *; do
if [ -d "$i" ]; then
echo $i
fi
done
并通过用分号替换新行来浓缩这一点(除了do
/之后then
):
for i in *; do if [ -d "$i" ]; then echo $i; fi; done
或者如前所述,只需在 Perl 中执行(我还没有测试到实际上取消注释 remove_tree - 小心!):
use strict;
use warnings;
use File::Path 'remove_tree';
use feature 'say';
chdir '/tmp';
opendir my $cache, '.';
while (my $item = readdir($cache)) {
if ($item !~ /^\.\.?$/ && -d $item) {
say "Deleting '$item'...";
# remove_tree($item);
}
}
使用系统
my @args = ("cd /home/faizan/test/cache ; for i in *; do if [ -d \"\$i\" ]; then echo \$i; fi; done");
system(@args);
使用子程序
sub do_stuff {
my @args = ( "bash", "-c", shift );
system(@args);
}
do_stuff("cd /home/faizan/test/cache ; for i in *; do if [ -d \"\$i\" ]; then echo \$i; fi; done");