在 bash 中从另一个目录执行命令

Tre*_*ham 167 bash

说我这样做:

cd subdir
git init
cd ../
Run Code Online (Sandbox Code Playgroud)

有没有办法用一个或两个命令来做到这一点,而不是为了在那里运行命令而必须进出目录?

(不是在寻找特定于 git 的解决方案;这只是一个例子。)

Mat*_*Mat 272

这通常是最好的方法:

( cd dir ; git init )
Run Code Online (Sandbox Code Playgroud)

或者

( cd dir && git init )
Run Code Online (Sandbox Code Playgroud)

它很短而且很容易打字。它确实启动了一个子外壳,因此您无法从中修改您的环境,但这在这里似乎不是问题。

  • @Francis.Beauchamp:如果您省略括号,您将在命令之后的子目录中,而不是回到您开始的地方。 (16认同)
  • 如果您确实需要设置一两个环境变量,只需在开头将其添加为另一个命令即可。 (2认同)

小智 25

我正在寻找一种从路径执行 git 命令的方法,并在不同的路径中对存储库进行更改。所以我在这里结束了这个问题。

但是对于我的特定需求,接受的答案和其他任何答案都没有帮助。

我需要使用sudo -u USER /usr/bin/git(另一个用户运行它)来运行 git 命令。正如你可能知道,须藤不允许我运行的cd命令,所以我不能成为存储库中的目录。

所以,我去了git 的手册页。在选项中,我看到了--git-dir=<path>

--git-dir=

设置存储库的路径。这也可以通过设置 GIT_DIR 环境变量来控制。它可以是当前工作目录的绝对路径或相对路径。

因此,如果它对某人有帮助,您仍然可以从路径中使用 git 并对“远离您”的存储库进行更改。只需使用:

git --git-dir=/path/to/repository GIT_COMMAND
Run Code Online (Sandbox Code Playgroud)

或者,要以其他用户身份运行它,请执行以下操作:

echo USER_PASSWORD | sudo -u USER_LOGIN -S /usr/bin/git --git-dir=/path/to/repository GIT_COMMAND
Run Code Online (Sandbox Code Playgroud)

同样来自git-init 的手册页

如果设置了 $GIT_DIR 环境变量,那么它指定一个路径来代替 ./.git 作为存储库的基础。

因此,如果您想在通常的 .git 文件夹下初始化存储库,您需要将它与--git-dir选项一起指定。例如:

echo USER_PASSWORD | sudo -u USER_LOGIN -S /usr/bin/git --git-dir=/path/to/repository/.git init
Run Code Online (Sandbox Code Playgroud)

在 上初始化存储库后/path/to/repo/.git,所有进一步的命令都应该有选项--work-tree=<path>,如 git 的手册页中所述:

--工作树=

设置工作树的路径。它可以是绝对路径,也可以是相对于当前工作目录的路径。这也可以通过设置 GIT_WORK_TREE 环境变量和 core.worktree 配置变量来控制(有关更详细的讨论,请参阅 git-config(1) 中的 core.worktree)。

因此,以另一个用户身份运行 git 并初始化新存储库的正确命令是:

echo USER_PASSWORD | sudo -u USER_LOGIN -S /usr/bin/git --git-dir=/path/to/repository/.git init
echo USER_PASSWORD | sudo -u USER_LOGIN -S /usr/bin/git --git-dir='/path/to/repository/.git' --work-tree='/path/to/repository' add /path/to/repository/*
echo USER_PASSWORD | sudo -u USER_LOGIN -S /usr/bin/git --git-dir='/path/to/repository/.git' --work-tree='/path/to/repository' commit -m 'MESSAGE'
echo USER_PASSWORD | sudo -u USER_LOGIN -S /usr/bin/git --git-dir='/path/to/repository/.git' --work-tree='/path/to/repository' remote add origin user@domain.com:path
echo USER_PASSWORD | sudo -u USER_LOGIN -S /usr/bin/git --git-dir='/path/to/repository/.git' --work-tree='/path/to/repository' push -u origin master
Run Code Online (Sandbox Code Playgroud)


Ric*_*lka 15

不完全是你要问的(你在上面的子shell中有真正的答案)但是看看pushdpopd


Wuf*_*ers 9

你有几个选择。您可以使用&&或对命令进行分组;。像这样:

cd subdir && git init && cd ..
Run Code Online (Sandbox Code Playgroud)

或者

cd subdir; git init; cd ..
Run Code Online (Sandbox Code Playgroud)

它们之间的区别在于,在第一个示例中,如果其中一个命令失败,则不会执行其余命令。在第二个示例中,无论如何所有命令都将运行。

另一种选择是定义一个函数并使用它,例如:

function cdinit() {
    cd $1
    git init
    cd ..
}
Run Code Online (Sandbox Code Playgroud)

然后你可以运行命令:

cdinit subdir
Run Code Online (Sandbox Code Playgroud)

它将自动git init进入该目录并移出该目录。

如果您有一堆目录并希望git init使用一个命令来处理它们,您还可以使用函数来执行更复杂的解决方案。

function cdinit() {
    for arg in $@
    do
        cd $arg
        git init
        cd ..
    done
}
Run Code Online (Sandbox Code Playgroud)

然后你可以运行它:

cdinit subdir1 subdir2 subdir3
Run Code Online (Sandbox Code Playgroud)

它会git initsubdir1, subdir2, 和 中完成subdir3


小智 5

在这种情况下git(至少在 2.7.0 版中),您可以利用-C使 git 表现得好像它是在给定目录中启动的选项。因此,您的解决方案可能如下所示:

> git -C subdir init
Initialized empty Git repository in /some/path/subdir/.git/
Run Code Online (Sandbox Code Playgroud)

引用文档:

Run as if git was started in <path> instead of the current working directory. When multiple -C options are given, each subsequent non-absolute -C
<path> is interpreted relative to the preceding -C <path>.

This option affects options that expect path name like --git-dir and --work-tree in that their interpretations of the path names would be made
relative to the working directory caused by the -C option. 
Run Code Online (Sandbox Code Playgroud)