Shell Script to Execute Shell Script to All Subdirectories
Solution 1
find will save you:
find /your/dir/with/subdirs -type d -exec sh -c 'cd "{}" ; /path/to/your/script.sh ;' \;
Solution 2
There are several problems in your script.
cd $MainDir
Better make this cd "$MainDir"
. Here this is not important, but it's a good habit to get into. If you leave a variable expansion unquoted, the value of the variable is split into words, and each word is treated as a shell wildcard pattern; so this command would fail if $MainDir
contained whitespace or \[?*
. Putting double quotes never hurts (unless you want splitting and filename matching to happen), and avoids these extra expansions. The same goes for command substitutions ($(somecommand)
). Always put double quotes around variable and command substitutions unless you know you want splitting and filename matching.
for dir in $(ls); do
Don't parse the output of ls
. You almost never need ls
in scripts. As explained above, the result of a command substitution is split into words that are treated as wildcard patterns, so $(ls)
mangles whitespace and wildcard characters, in addition to the mangling of non-printable characters that ls
may do. Listing the file names in a directory is built into the shell:
for dir in *; do
If you make that for dir in */; do
, only subdirectories of the current directory are matched, not other kinds of files.
if [ -f $dir/sysconfig.out];
You need whitespace on each side of the brackets, except when the character next to it is a shell punctuation character: ();&|<>
. And again, put double quotes around the variable substitutions (this goes for every other place where you have a variable substitution): if [ -f "$dir/sysconfig.out" ];
#cd back to where we started cd $OLDPWD
This is useless: the process is about to exit, changing its current directory won't affect anything. Note that each process has its own current directory: changing it in a script does not affect the program that called the script.
Turning to the reason you asked this question, it isn't clear what you want. “binary file /some/subdirectory/
” doesn't make much sense: you wouldn't get this message with a directory. For better help, copy-paste the error message. You should always copy-paste error messages when you ask for help online.
From your description, it seems that files have moved one directory level deeper. If that's the case, change the line for dir in */; do
to
for dir in */*/; do
Solution 3
There are numerous ways you could do this. you could either run your existing script in a for loop, or use find and xargs, or perhaps even make use of grep's -r
aka --recursive
option.
The simplest is probably just to write a for loop wrapper around your existing script. For example:
#! /bin/bash
cd /path/to/top/level/directory
for d in */ ; do
pushd $d
# call your script here
popd
done
Related videos on Youtube
Comments
-
JudeJitsu over 1 year
I am making a script to simplify my daily tasks. Everyday, I have to grep for a few things inside a company server. It was okay, however, now, they have segregated each object into sub directories. I am looking for a solution in which my existing shell script will execute repeatedly into each sub directory inside a certain directory. How do I do this? I am quite new to Linux and still learning the ropes.
Here's my script:
#!/bin/bash MainDir=/path/to/dir/containing/subdirs # cd into dir cd $MainDir for dir in $(ls); do #fetch start time of uut grep -i "01_node_setup" $dir/his_file | tail -1 >> /home/xtee/sst-logs.out #check if sysconfig.out exists if [ -f $dir/sysconfig.out]; then grep -A 1 "Drive Model" $dir/sysconfig.out | tail -1 >> /home/xtee/sst-logs.out else grep -m 1 "Pair0 DIMM0" $dir/node0/trans_file_prev/*setupsys* | tail -1 >> /home/xtee/sst-logs.out fi done #cd back to where we started cd $OLDPWD
A nice guy helped me with the script, and the script above is what came out. It worked alright however, the sst-logs.out file displays
binary file /some/subdirectory/
instead of the output of the grep. What is wrong in the script?-
Marco almost 12 yearsDoes the grep switch
-R
for recursive help? -
JudeJitsu almost 12 years@Marco, it might if the subdirectories contain only one each file name i am grepping to which is not the case. the subdirectories also have their own subdirectories which has the file with the same file name (e.g. history) which i do not want...
-
-
JudeJitsu almost 12 yearsThanks Craig. Will try this... Appreciate the help :) Can this be done to CD just one sub directory deep? Because the subdirectories have their own "history" subdirectory which contains the same file name.
-
JudeJitsu almost 12 yearsThanks rush... Will also try this. I am looking for the lightest implementation.. :)
-
Alessio almost 12 yearsas written, it only iterates through the first-level subdirectories of your top-level directory. i.e. yes. if you needed it to process every subdirectory below that you'd have to do something like
for d in $(find . -type d); do ...