我有一个脚本/home/user/me/my_script.sh,该脚本应该遍历多个目录并处理文件。我当前的工作目录是/ home / user / me。调用ls -R会产生:
./项目:
dir1 dir2 dir3
./ projects / dir1:
image1.ntf points2.csv image1.img image1.hdr
./ projects / dir2:
image2.ntf points2.csv image2.img image2.hdr
./ projects / dir3:
image3.ntf points3.csv image3.img image3.hdr
我有这个脚本:
#! /bin/bash -f
for $dir in $1*
do
echo $dir
set cmd = `/home/tools/tool.sh -i $dir/*.ntf -flag1 -flag2 -flag3 opt3`
$cmd
done
这是它的运行方式(来自cwd / home / user / me)和结果:
bash-4.1$ ./myscript.sh projects/
projects/*
bash-4.1$
这不是预期的输出。预期的输出是:
bash-4.1$ ./myscript.sh projects/
projects/dir1
[output from tool.sh]
projects/dir2
[output from tool.sh]
projects/dir3
[output from tool.sh]
bash-4.1$
应该发生的是,脚本应该进入第一个目录,找到* .ntf文件并将其传递给tool.sh。到那时,我将开始看到该工具的输出。我已经在单个文件上运行了该工具:
bash-4.1$ /home/tools/tool.sh -i /home/user/me/projects/dir1/image1.ntf -flag1 -flag2 -flag3 opt3
[expected output from tool. lengthy.]
bash-4.1$
我尝试在以下位置找到语法:How to loop over directories in Linux?和此处:Looping over directories in Bash
for $dir in /$1*/
do ...
结果:
bash-4.1$ ./myscript.sh projects/
/projects/*/
并且:
for $dir in $1/*
do ...
结果:
bash-4.1$ ./myscript.sh projects
projects/*
我不确定我还能提出多少其他通配符和斜杠迭代。正确的语法是什么?
答案 0 :(得分:2)
首先,您应该在shebang中删除标记-f
,因为这完全意味着:
$ man bash […] -f Disable pathname expansion.
第二,有一些典型的错误模式:变量周围缺少空格(写"$dir"
以应对包含空格的目录名),在$
行中有一个虚假的for
(根据您的说法,请写for dir in "$1"*
),而不是set
行(set
是内置的shell,仅用于更改shell的配置,例如set -x
)。回答@ghoti的问题,似乎不需要$cmd
行。同样,不赞成使用反引号语法,并且可以将其替换为cmd=$(/home/tools/tool.sh -i "$dir"/*.ntf -flag1 -flag2 -flag3 opt3)
。
这将导致以下脚本:
#!/bin/bash for dir in "$1"* do [[ -d "$dir" ]] || continue # only consider existing folders printf "%s=%q\n" dir "$dir" /home/tools/tool.sh -i "$dir"/*.ntf -flag1 -flag2 -flag3 opt3 done
顺便说一句,我建议您始终在Bash脚本上运行ShellCheck静态分析器,以检测典型的错误并获得反馈。好的做法。如果您使用的是Linux发行版,则应可安装with your standard package manager。