Linux

將命令儲存在變數中而不進行評估 - Unix

  • July 18, 2018

我正在嘗試將命令儲存在變數中,以便以後可以在遠端伺服器上執行。星號被替換為文件夾名稱並儲存在變數中。我需要該命令與以後使用的星號相同。

腳本:

#!/bin/bash
cmd="ls -lrt /client/*/ver* /client/*/*/ver*  | grep 299 | tail -1"
echo $cmd

輸出:

./script.sh 
ls -lrt /client/folder299/version_1 /client/ifolder299/ifolder/version_a /client/ifolder300/ifolder1/version_b /client/ifolder301/ifolder2/version_c /client/ifolder302/ifolder3/version_d | grep 299 | tail -1

我試著四處尋找沒有運氣。有人可以幫助我按原樣儲存命令嗎?

該命令不被評估,字元串按原樣儲存在變數中。當您輸出未引用的變數時,它是擴展的萬用字元模式。


cmd="ls -lrt /client/*/ver* /client/*/*/ver*  | grep 299 | tail -1"

這是安全的,並將設置cmd為文字 string ls -lrt /client/*/ver* /client/*/*/ver* | grep 299 | tail -1。在這種情況下,在字元串周圍使用雙引號和單引號之間的區別並不重要(但我會使用單引號,因為這是一個靜態字元串)。從某種意義上說,shell 在字元串中沒有任何擴展,這並不重要。如果字元串中有變數或命令替換,shell 會擴展這些,但沒有。

當您使用輸出變數的值時echo $cmd,通配模式將被擴展(這就是發生的情況),但該命令仍不會執行。

要阻止 globbing 模式被擴展,請將變數擴展雙引號為"$cmd". 就個人而言,我會使用

printf '%s\n' "$cmd"

列印它的值。請參閱“為什麼 printf 比 echo 更好? ”了解原因。

有關的:


另請注意,由於您正在解析ls -l(其本身並不安全)的輸出,然後使用 grepping 查找數字,因此您可以從輸出中的任何位置ls -l(例如文件大小)中提取該數字。

我建議您重新考慮您要解決的更大的問題是什麼,然後提出一個全新的問題

要從路徑名列表中查找最近修改的正常文件,您可以這樣做

unset newest
for pathname in /client/*/ver* /client/*/*/ver*; do
   if [ -f "$pathname" ] && [ "$pathname" -nt "$newest" ]; then
       newest=$pathname
   fi
done

這是假設您提到的文件名通配模式擴展為您要檢查的名稱。要另外限制它只允許包含字元串的文件名299

unset newest
for pathname in /client/*/ver* /client/*/*/ver*; do
   if [[ "${pathname##*/}" == *299* ]] &&
       [ -f "$pathname" ] && [ "$pathname" -nt "$newest" ]; then
       newest=$pathname
   fi
done

如果 globbing 模式擴展到您需要遞歸查看的目錄,則使用bash

shopt -s globstar
unset newest
for pathname in /client/*/ver*/** /client/*/*/ver*/**; do
   if [[ "${pathname##*/}" == *299* ]] &&
       [ -f "$pathname" ] && [ "$pathname" -nt "$newest" ]; then
       newest=$pathname
   fi
done

通過 SSH 執行的範例:

ssh user@host bash -s -O globstar <<'END_SCRIPT'
for pathname in /client/*/ver*/** /client/*/*/ver*/**; do
   if [[ "${pathname##*/}" == *299* ]] &&
       [ -f "$pathname" ] && [ "$pathname" -nt "$newest" ]; then
       newest=$pathname
   fi
done
printf 'Newest file: %s\n' "$newest"
END_SCRIPT

引用自:https://unix.stackexchange.com/questions/454619