1. 程式人生 > 其它 >【Shell】xargs的高階用法

【Shell】xargs的高階用法

看一個專案中經常用到的下程式碼方法:
一、已知條件:
知道gerrit服務域名與埠(一般預設都是29418),有下程式碼許可權;通過測試命令看是否有許可權,簡單測試命令如下:

ssh -p 29418 xxxx.xxx.xxx

二、下程式碼原理:
1.通過ssh命令獲取到所有的project;
2.逐個git初始化project倉庫(git init --bare xxx.git);
3.逐個倉庫fetch (git fetch --all)
三、知識點梳理:
1⃣️

ssh -p 29418 xxxx.xxx.xxx gerrit --help
ssh -p 29418 xxxx.xxx.xxx gerrit ls-projects --help
ssh -p 29418 xxxx.xxx.xxx gerrit ls-projects --type CODE  -r REGEX

2⃣️

shuf:把輸入行按隨機順序輸出到標準輸出。


用法: shuf [選項]... [檔案]
 或者:  shuf -e [選項]... [引數]...
 或者:  shuf -i LO-HI [選項]...


常用引數:
  -e, --echo			將每個引數視為輸入行
  -i, --input-range=LO-HI	將LO 到HI 的每個數字視為輸入行
  -n, --head-count=行數		最多輸出指定的行數
  -o, --output=檔案		將結果輸出到指定檔案而非標準輸出
      --random-source=檔案	從指定檔案獲得隨機位元
  -z, --zero-terminated	以0 結束行而非新行
      --help		顯示此幫助資訊並退出
      --version		顯示版本資訊並退出


如果沒有指定檔案,或者檔案為"-",則從標準輸入讀取。

3⃣️

xargs命令的作用,是將標準輸入轉為命令列引數。
真正執行的命令,緊跟在xargs後面,接受xargs傳來的引數。
xargs的作用在於,大多數命令(比如rm、mkdir、ls)與管道一起使用時,都需要xargs將標準輸入轉為命令列引數。
$ echo "one two three" | xargs mkdir
上面的程式碼等同於mkdir one two three。如果不加xargs就會報錯,提示mkdir缺少操作引數。
$ echo "hello world" | xargs echo
hello world

http://www.ruanyifeng.com/blog/2019/08/xargs-tutorial.html


四、實際專案中用到的shell指令碼函式:

function git_clone_all(){
    local L_REGEX="$1"  # REGEX 正則匹配需要獲取哪個目錄下的所有的git倉庫

    local L_LENGTH="$2"  # 去掉開頭git倉庫路徑,如果cd到其下子目錄了。這裡需要去掉。

    ssh -p ${gerrit_port} ${gerrit_host} gerrit ls-projects --type CODE -r "${L_REGEX}" | shuf | xargs -r -n1 -P4 -I% bash -c '
    L_LOCAL_GIT=${1:${2}}.git  
    #shell字串切片:${variable_name:start_position:length} 
    # $ string=abcdefghijklmnopqrstuvwxyz 
    # $ echo ${string:4} efghijklmnopqrstuvwxyz
    L_REMOTE_GIT=${3}/${1}

    echo "will init for ${L_LOCAL_GIT} with ${L_REMOTE_GIT}"

    git init --quiet --bare ${L_LOCAL_GIT}

    cat >${L_LOCAL_GIT}/config <<EOF
[core]
	repositoryformatversion = 0
	filemode = true
	bare = true
[remote "origin"]
	url = ${L_REMOTE_GIT}
	fetch = +refs/*:refs/*
	mirror = true
EOF
    find ${L_LOCAL_GIT}/objects -type f -empty -delete -print #查詢空物件檔案刪除
    find ${L_LOCAL_GIT}/refs -type f -empty -delete -print
    git -C ${L_LOCAL_GIT} fetch --all

    ' "_" "%" "${L_LENGTH}" "ssh://${gerrit_host}:${gerrit_port}"

}