Bash
如何將命令的輸出分配給 shell 變數?
我想將表達式的結果(即命令的輸出)分配給一個變數,然後對其進行操作——例如,將它與一個字元串連接,然後回顯它。這是我所擁有的:
#!/bin/bash cd ~/Desktop; thefile= ls -t -U | grep -m 1 "Screen Shot"; echo "Most recent screenshot is: "$thefile;
但這會輸出:
Screen Shot 2011-07-03 at 1.55.43 PM.png Most recent screenshot is:
因此,看起來它沒有被分配給
$thefile
,並且在執行時正在列印。我錯過了什麼?
shell 賦值是一個單詞,等號後沒有空格。因此,您編寫的內容將空值分配給
thefile
; 此外,由於分配與命令組合在一起,因此它創建thefile
了一個環境變數,並且分配對於該特定命令是本地的,即只有呼叫才能ls
看到分配的值。您想擷取命令的輸出,因此需要使用命令替換:
thefile=$(ls -t -U | grep -m 1 "Screen Shot")
(一些文獻顯示了另一種語法
thefile=
ls …`` ;反引號語法等同於美元括號語法,只是在反引號內引用有時很奇怪,所以只需使用$(…)
.)關於您的腳本的其他說明:
- 將
-t
(sort by time) 與-U
(don’t sort with GNUls
) 結合是沒有意義的;只需使用-t
.- 與其使用匹配螢幕截圖,不如將
grep
萬用字元傳遞給ls
並用於head
擷取第一個文件更清晰:thefile=$(ls -td -- *"Screen Shot"* | head -n 1)
- 解析
ls
. _ 如果您的文件名包含不可列印的字元,這可能會非常失敗。但是,如果沒有 ,按日期對文件進行排序是很困難ls
的,因此如果您知道文件名中沒有不可列印的字元或反斜杠,這是一個可以接受的解決方案。- 總是在變數替換周圍使用雙引號,即在這裡寫
echo "Most recent screenshot is: $thefile"
如果沒有雙引號,變數的值會被重新展開,如果它包含空格或其他特殊字元會造成麻煩。
- 行尾不需要分號。它們是多餘的但無害的。
- 在 shell 腳本中,包含
set -e
. 如果任何命令失敗(通過返回非零狀態),這會告訴 shell 退出。如果您有 GNU
find
andsort
(特別是如果您執行的是非嵌入式 Linux 或 Cygwin),還有另一種查找最新文件的方法:find
列出文件及其日期,然後使用sort
andread
(這裡假設bash
或zsh
for-d ''
讀取NUL 分隔的記錄)來提取最年輕的文件。IFS=/ read -rd '' ignored thefile < <( find -maxdepth 1 -type f -name "*Screen Shot*" -printf "%T@/%p\0" | sort -rnz)
如果您願意在 zsh 而不是 bash 中編寫此腳本,則有一種更簡單的方法來擷取最新文件,因為 zsh 具有glob 限定符,不僅允許在名稱上匹配萬用字元,還允許在文件元數據上匹配萬用字元。模式之後的
(om[1])
部分是 glob 限定符;om
通過增加年齡(即按修改時間,最新的在前)對匹配項進行排序,並[1]
僅提取第一個匹配項。整個匹配需要放在括號中,因為它在技術上是一個數組,因為 globbing 返回一個文件列表,即使這[1]
意味著在這種特殊情況下該列表包含(最多)一個文件。#!/bin/zsh set -e cd ~/Desktop thefile=(*"Screen Shot"*(om[1])) print -r "Most recent screenshot is: $thefile"