2014-09-19 43 views
1

我想就把電話EA之間的睡眠捲曲鏈命令:可以使用xargs的

ssh [email protected] "cd /export/home/someone && find . -name '*' -print| xargs -n1 curl -u someone:password ftp://somehost/tmp/ -vT" 

不知道是可以做到的。已經嘗試了幾十個排列組合。可以在開始/結束時進行睡眠,但不能在兩者之間進行。 非常感謝

+0

你能不能只是做'第一個命令;睡10次;第二個命令「或」第一個命令&&睡眠10 |「第二個命令「,如果你必須管道? – 2014-09-19 14:55:32

+1

你爲什麼需要睡覺?另外,它似乎是'find/export/home/someone -exec curl -u someone:password -vT {} ftp:// somehost/tmp /'也可以。 – chepner 2014-09-19 15:29:28

+0

如果你使用'bash' 4,你甚至不需要'find':'shopt -s globstar; curl -u某人:密碼-vT/export/home/someone/**/*' – chepner 2014-09-19 15:30:45

回答

-1

你可以在那裏使用一個循環。

ssh [email protected] "for i in `ls`; do curl -u someone:password ftp://somehost/tmp/ -vT ; sleep 10;done" 
+2

[不要從'ls'解析輸出](http://mywiki.wooledge.org/ParsingLs)讓shell它爲你填充。 '因爲我在*;'。 – 2014-09-19 15:00:50

2

xargs接受單個命令。你需要讓這個單一命令做兩件事。

嘗試

| xargs -n1 bash -c 'curl ... "$0"; sleep ##' 

或(使用你需要手動$0填寫 「正常」 位置參數)。

| xargs -n1 bash -c 'curl ... "$1"; sleep 1' - 
+0

我可能會過分詮釋這個相當電報的問題,但我有一種印象,他們不想在開始或結束時睡覺,只是在兩者之間。 – rici 2014-09-19 18:43:23

+0

@rici我認爲你對請求進行了過度解釋。我認爲重要的一點是,他們可能已經在開始*或者*系列結束時進入休眠狀態,但不會在兩次調用之間進行休眠(以實現請求之間的延遲,比如'wget -w'),而不是休眠在開始/結束時是不可接受的。但你的解釋當然要難得多。 – 2014-09-19 19:08:24

0

相反的xargs你可以使用一個子shell:

ssh [email protected] 'cd /export/home/someone && find . -name "*" -print| (while read file; do curl -u someone:password ftp://somehost/tmp/ -vT "$file"; sleep 10; done)' 

請注意,我也翻你的單,雙引號,以便本地shell不會試圖解釋$file

2

這個問題的有趣的部分是讓捲髮之間的睡眠,而不是在捲髮序列的開始或結束。

如果你沒有太多的文件,爲「太多」一些值[注1]

find . -type f --exec bash -c ' 
    doit() { curl -u someone:password ftp://somehost/tmp/ -vT; } 
    doit "$1"; for f in "${@:2}"; sleep 2; doit "$f"; done 
    ' _ {} + 

我改變了find標準從-name *(它將匹配所有的文件和目錄)到-type f,它只會匹配普通文件。

上述命令行工作方式是使用find調用(與--exec)明確子shell(bash -c)傳遞給它的大量的文件名作爲參數({} +)。 (_是因爲bash -c script的第一個參數取$0,而不是$1。)提供給bash -c的腳本只是通過其參數循環使用便利功能doit(如果您想將此想法用於一個不同的命令)。

有可能你並不真的需要find,因爲你實際上並不關心遞歸匹配,在這種情況下,你可以簡化一下。另外,使用bash 4,你可以使用**來進行遞歸匹配,但**也會匹配子目錄,所以你需要將它們過濾掉。

這裏有一個bash 4例如:

doit() { curl -u someone:password ftp://somehost/tmp/ -vT; } 
shopt -s globstar 
sleep= 
for f in **; do if [[ -f $f ]]; then 
    $sleep 
    doit "$f" 
    sleep="sleep 2" 
fi done 

注:

  1. 不幸的是,文件的最大數量是系統相關的,並且依賴於可用內存參數和環境量變量(並因此取決於環境變量的總大小)。在我的系統上(Ubuntu),最大值大約爲128千字節的文件名,這可能是幾千個文件,除非你使用真正的長文件名。如果超出此限制,將會多次執行bash -c調用,並且在第二次調用和後續調用之前不會有睡眠,這意味着每上千次中有一個文件將在沒有預先睡眠的情況下上傳。另一方面,2000個文件的睡眠加起來超過一個小時,所以我不認爲這個限制很可能適用。
0

如果你有GNU並行你可以運行:

ssh [email protected] "cd /export/home/someone && find . -name '*' -print | 
    parallel -j1 'sleep 10;curl -u someone:password ftp://somehost/tmp/ -vT' 

所有新計算機具有多個核心,但大多數程序在性質上串行,因此不會使用多個內核。然而,許多任務十分parallelizeable:

  • 上有許多文件運行同一程序
  • 運行在一個文件
  • 運行在一個文件中的每個塊的同一個程序的每一行同一程序

GNU並行是一個通用的並行程序,可以很容易地在同一臺機器或多臺你有ssh訪問的機器上並行運行作業。

如果你想在4個CPU上運行32個不同的工作崗位,並行化直接的方式是在每個CPU上運行8個作業:

Simple scheduling

GNU並行,而不是產生一個新的進程時,一個完成 - 保持CPU的活躍,從而節省了時間:

GNU Parallel scheduling

安裝

個人安裝不需要root訪問權限。它可以在10秒內通過這樣來完成:

(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash 

對於其他安裝選項見http://git.savannah.gnu.org/cgit/parallel.git/tree/README

瞭解更多

查看更多的例子:http://www.gnu.org/software/parallel/man.html

觀看介紹視頻: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

走過t他教程:http://www.gnu.org/software/parallel/parallel_tutorial.html

訂閱郵件列表,以獲得支持:https://lists.gnu.org/mailman/listinfo/parallel