bash 在所有直接子目录中执行命令

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/41553325/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 15:35:52  来源:igfitidea点击:

Execute command in all immediate subdirectories

bashshellzsh

提问by Zahymaka

I'm trying to add a shell function (zsh) mexecto execute the same command in all immediate subdirectories e.g. with the following structure

我正在尝试添加一个 shell 函数 (zsh)mexec以在所有直接子目录中执行相同的命令,例如具有以下结构

~
-- folder1
-- folder2

mexec pwdwould show for example

mexec pwd会显示例如

/home/me/folder1
/home/me/folder2

I'm using findto pull the immediate subdirectories. The problem is getting the passed in command to execute. Here's my first function defintion:

我正在使用find拉直接子目录。问题是让传入的命令执行。这是我的第一个函数定义:

mexec() {
    find . -mindepth 1 -maxdepth 1 -type d | xargs -I'{}' \
    /bin/zsh -c "cd {} && $@;";
}

only executes the command itself but doesn't pass in the arguments i.e. mexec ls -albehaves exactly like ls

只执行命令本身,但不传递参数,即mexec ls -al行为完全像ls

Changing the second line to /bin/zsh -c "(cd {} && $@);", mexecworks for just mexec lsbut shows this error for mexec ls -al:

将第二行更改为/bin/zsh -c "(cd {} && $@);",mexec仅适用于mexec ls但显示以下错误mexec ls -al

zsh:1: parse error near `ls'

Going the exec route with find

使用 find 走 exec 路线

find . -mindepth 1 -maxdepth 1 -type d -exec /bin/zsh -c "(cd {} && $@)" \;

Gives me the same thing which leads me to believe there's a problem with how I'm passing the arguments to zsh. This also seems to be a problem if I use bash: the error shown is:

给了我同样的事情,这让我相信我将参数传递给 zsh 的方式存在问题。如果我使用 bash,这似乎也是一个问题:显示的错误是:

-a);: -c: line 1: syntax error: unexpected end of file

What would be a good way to achieve this?

实现这一目标的好方法是什么?

回答by Inian

Can you try using this simple loop which loops in all sub-directories at one level deep and execute commands on it,

您可以尝试使用这个简单的循环,它会在所有子目录中的一层深度循环并在其上执行命令,

for d in ./*/ ; do (cd "$d" && ls -al); done

(cmd1 && cmd2)opens a sub-shell to run the commands. Since it is a child shell, the parent shell (the shell from which you're running this command) retains its current folder and other environment variables.

(cmd1 && cmd2)打开一个子shell来运行命令。由于它是一个子 shell,父 shell(您从中运行此命令的 shell)保留其当前文件夹和其他环境变量。

Wrap it around in a function in a proper zshscript as

将它包装在一个适当zsh脚本的函数中,如下所示

#!/bin/zsh

function runCommand() {
    for d in ./*/ ; do /bin/zsh -c "(cd "$d" && "$@")"; done
}

runCommand "ls -al"

should work just fine for you.

应该适合你。

回答by wilsotc

#!/bin/zsh
# A simple script with a function...

mexec()
{ 
  export THE_COMMAND=$@
  find . -type d -maxdepth 1 -mindepth 1 -print0 | xargs -0 -I{} zsh -c 'cd "{}" && echo "{}" && echo "$('$THE_COMMAND')" && echo -e'
}

mexec ls -al