I am building a generic function exec_all_dirs
in bashrc that would run a command in multiple directories.
function exec_all_dirs() {
curdir=$PWD
dirs=(
~/dir1
~/dir2
~/dir3
)
for dir in ${dirs[@]};
do
echo "---------- $dir ---------"
"$@" # run the command here.
done
cd $curdir
}
function all_func() {
exec_all_dirs 'cd $dir && another_func_defined_in_bashrc' # how to pass $dir
}
function all_du() {
exec_all_dirs 'du -sh $dir'
}
How can I pass $dir
as argument to exec_all_dirs
so it gets expanded in the for loop?
CodePudding user response:
Instead, consider a different approach, way safer and easier to use. Work just like xargs
works. Allow passing the command, as-is separated by words, to your command. Then define the work in a separate function. that way you won't have to handle putting it all in single quotes. Pass variable context "$dir"
as a positional argument to the command.
exec_all_dirs() {
local curdir dirs
curdir=$PWD
dirs=(
~/dir1
~/dir2
~/dir3
)
for dir in "${dirs[@]}"; do
echo "---------- $dir ---------"
"$@" "$dir"
done
cd $curdir
}
_all_func_in() {
if cd "$1"; then
another_func_defined_in_bashrc
fi
}
all_func() {
exec_all_dirs _all_func_in
}
all_du() {
exec_all_dirs du -sh
}
Check your scripts with shellcheck. Do not use function name()
- just name()
.
How can I pass $dir as argument to exec_all_dirs so it gets expanded in the for loop?
You can replace it yourself:
echo "$1" | sed 's/$dir/'"$dir"'/g'
You can just run eval
:
eval "$@"
CodePudding user response:
Try like this:
exec_all_dirs(){
local curdir=$PDW
local cmd dir
local dirs=(
~/dir1
~/dir2
~/dir3
)
for dir in ${dirs[@]}; do
echo "---------- $dir ---------"
printf -v cmd "$1" "$dir"
bash -c "$cmd"
done
cd $curdir
}
all_fu(){ exec_all_dirs 'cd %s && another_func_defined_in_bashrc'; }
all_du(){ exec_all_dirs 'du -sh %s'; }