題 從bash中的另一個目錄執行命令


說我這樣做:

cd subdir
git init
cd ../

有沒有辦法用一個命令,或者兩個命令來執行此操作,而不是必須移入和移出目錄才能在那裡運行命令?

(不是尋找特定於git的解決方案;這只是一個例子。)


97
2018-04-17 16:05


起源




答案:


這通常是最好的方法:

( cd dir ; git init )

要么

( cd dir && git init )

它非常簡短,易於打字。它確實啟動了一個子shell,所以你不能從那裡修改你的環境,但這似乎不是一個問題。


170
2018-04-17 16:27



如果您確實需要設置一個或兩個環境變量,只需在開頭添加另一個命令即可。 - Hippo
@CraigMcQueen:不是。 $? 將包含在子shell中運行的最後一個命令的退出代碼。如果你使用 && 變體(你通常應該這樣),然後你會得到失敗的第一個命令的退出代碼(如果一切正常則為0)。 - Mat
我認為括號是可選的 - Francis.Beauchamp
@Francis.Beauchamp:如果你省略了parens,你將在命令後面的子目錄中,而不是回到你開始的地方。 - Mat


我一直在尋找一種從路徑執行git命令的方法,並在不同的路徑中對存儲庫進行更改。所以我在這裡結束了這個問題。

但是對於我的具體需求,既然接受的答案也沒有其他任何答案。

我需要使用運行git命令 sudo -u USER /usr/bin/git (運行它的另一個用戶)。而你可能知道,sudo不允許我運行 cd 命令,所以我不能  在存儲庫目錄中。

所以,我去了 git的手冊頁。在選項中,我看到了 --git-dir=<path>

--git-DIR =

設置存儲庫的路徑。這也可以通過設置GIT_DIR環境變量來控制。它可以是當前工作目錄的絕對路徑或相對路徑。

因此,如果它對某人有幫助,您仍然可以使用路徑中的git並對“遠離您”的存儲庫進行更改。只需使用:

git --git-dir=/path/to/repository GIT_COMMAND

或者,以另一個用戶身份運行它,執行以下操作:

echo USER_PASSWORD | sudo -u USER_LOGIN -S /usr/bin/git --git-dir=/path/to/repository GIT_COMMAND

也來自 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

在初始化存儲庫之後 /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

21
2018-06-20 23:56



如果您以交互方式使用sudo而不是通過腳本,那麼您可以這樣做 sudo -i 要么 sudo su 獲得一個交互式root shell。 - Bugster


不完全是你所要求的(你在上面的子shell中有真正的答案),但看看 pushd 和 popd


12
2018-04-17 17:39



我嘗試使用cd &&作為maven並且它不起作用,但pushd和popd完美地完成了這項工作。謝謝 - Radu Toader


你有幾個選擇。您可以使用命令對命令進行分組 && 要么 ;。像這樣:

cd subdir && git init && cd ..

要么

cd subdir; git init; cd ..

它們之間的區別在於,在第一個示例中,如果其中一個命令失敗,則不會執行其餘命令。在第二個示例中,無論如何,所有命令都將運行。

另一種選擇是定義一個函數並使用它,例如:

function cdinit() {
    cd $1
    git init
    cd ..
}

然後你可以運行命令:

cdinit subdir

它會自動完成 git init 在該目錄中並移出它。

如果你有一堆目錄並想要,你也可以使用函數做一個更複雜的解決方案 git init 他們只用一個命令。

function cdinit() {
    for arg in $@
    do
        cd $arg
        git init
        cd ..
    done
}

然後你可以運行:

cdinit subdir1 subdir2 subdir3

它會做的 git init 在 subdir1subdir2,和 subdir3


5
2018-04-17 16:17



謝謝。我知道 && 和 ;,但希望更優雅的東西。聽起來像寫腳本是我最好的選擇。 - Trevor Burnham
更正:這個答案很好,但Mat的答案更適合我的特殊需求。 - Trevor Burnham


的情況下 git (至少在2.7.0版本中),您可以利用 -C 使git表現得像在給定目錄中啟動的選項。所以你的解決方案看起來像:

> git -C subdir init
Initialized empty Git repository in /some/path/subdir/.git/

引用文檔:

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. 

5
2018-02-19 15:14





您可以使用&&對命令進行分組,即

cd subdir && git init && cd ../

如果您不希望任何依賴於每個命令的退出代碼,您可以使用;相反,即:

cd subdir ; git init ; cd ../

2
2018-04-17 16:09



或者 ; 這樣它們就不依賴於前一個的返回碼。 - slhck


如果命令沒有文件名或目錄名參數,則必須跳轉到目標目錄。

但是您可以編寫一個bash腳本,將目標目錄和命令作為參數。 為此你可以看看pushd和popd: http://ss64.com/bash/pushd.html

我會為你寫那個小腳本,但我這裡沒有Linux盒子:)


2
2018-04-17 16:18



剛剛看到Mark Szymanski的答案。你可以為命令實現第二個參數(並重命名命令),你就擁有了你想要的東西。 - wullxz


程序有不同的處理參數的方法,所以一些程序會有一些等價的 -folder =名稱 選項。除了這個例外,即使在MS DOS上,標準也很簡單

$ 程序 子目錄

有時你需要

$ 程序 子目錄/

程序將打開文件夾,以與處理文件相同的方式使用它,一旦完成,將控制權返回到shell,該shell指向您的原始標準目錄。 以這種方式處理的程序DO存在錯誤輸出(如核心轉儲)轉到shell當前目錄中的文件的問題(而不是 子目錄。)

除非程序具有可用於指定其他位置的命令開關,否則沒有解決方法。一些程序員在“目錄程序之間取得藝術許可證 來自“和”目錄程序是 告訴上班 “。


1
2018-04-17 16:40