Bash

if…then 語句的分組命令,包括在一行中為 shell/bash 分配變數

  • August 15, 2022

我知道*while-do-done的存在。或者,我知道我可以使用for-do-done。但是,我試圖使用if-then-else*手動測試。

我想執行一個命令,但在每次迭代中進行加法轉換。

sh-3.2# currPos=0;stepSize=16;
sh-3.2# hexdump -n $stepSize -Cv /dev/disk0s1 -s $currPos;currPos=$(($currPos + $stepSize));echo $currPos;
00000000  8d 1c 09 48 65 8c 3c 6e  01 00 00 00 00 00 00 00  |...He.<n........|
00000010
16
sh-3.2# hexdump -n $stepSize -Cv /dev/disk0s1 -s $currPos;currPos=$(($currPos + $stepSize));echo $currPos;
00000000  8d 1c 09 48 65 8c 3c 6e  01 00 00 00 00 00 00 00  |...He.<n........|
00000010
32
sh-3.2# hexdump -n $stepSize -Cv /dev/disk0s1 -s $currPos;currPos=$(($currPos + $stepSize));echo $currPos;
00000000  8d 1c 09 48 65 8c 3c 6e  01 00 00 00 00 00 00 00  |...He.<n........|
00000010
48
sh-3.2# 

如您所見,offset( -s) 沒有採用 variable 的更新值$currPos。但在echo命令中,$currPos變數正在改變(163248)!

編輯1:根據Kusalananda(非常感謝!)我修復了第一步。

sh-3.2# currPos=0;stepSize=16;finalStep=48;
sh-3.2# hexdump -n $stepSize -Cv -s $currPos /dev/disk0s1;currPos=$(($currPos + $stepSize));echo $currPos;
00000000  8d 1c 09 48 65 8c 3c 6e  01 00 00 00 00 00 00 00  |...He.<n........|
00000010
16
sh-3.2# hexdump -n $stepSize -Cv -s $currPos /dev/disk0s1;currPos=$(($currPos + $stepSize));echo $currPos;
00000010  bd 04 00 00 00 00 00 00  01 00 00 80 00 00 00 00  |................|
00000020
32
sh-3.2# hexdump -n $stepSize -Cv -s $currPos /dev/disk0s1;currPos=$(($currPos + $stepSize));echo $currPos;
00000020  4e 58 53 42 00 10 00 00  00 f4 01 00 00 00 00 00  |NXSB............|
00000030
48

讓我們從:https ://linuxize.com/post/bash-if-else-statement/ 中使用:if, then, else, fiand ( -eq, -gt, -ge, -lt, -le, !=) 和break.

if嘗試對,使用迭代break

sh-3.2# currPos=0;stepSize=16;finalStep=48;
sh-3.2# if [ $currPos -le $finalStep ]; then (hexdump -n $stepSize -Cv /dev/disk0s1 -s $currPos;currPos=$(($currPos + $stepSize));echo $currPos;); else break; fi
00000000  8d 1c 09 48 65 8c 3c 6e  01 00 00 00 00 00 00 00  |...He.<n........|
00000010
16
sh-3.2# if [ $currPos -le $finalStep ]; then (hexdump -n $stepSize -Cv /dev/disk0s1 -s $currPos;currPos=$(($currPos + $stepSize));echo $currPos;); else break; fi
00000000  8d 1c 09 48 65 8c 3c 6e  01 00 00 00 00 00 00 00  |...He.<n........|
00000010
16
sh-3.2# if [ $currPos -le $finalStep ]; then (hexdump -n $stepSize -Cv /dev/disk0s1 -s $currPos;currPos=$(($currPos + $stepSize));echo $currPos;); else break; fi
00000000  8d 1c 09 48 65 8c 3c 6e  01 00 00 00 00 00 00 00  |...He.<n........|
00000010
16

Note:我在語句的內部()命令(hexdumpassignationecho)中進行分組。then``if

但是,在這種情況下,第echo一種情況下工作最差($currPos變數的值沒有改變)。

根據這篇文章,我需要使用{and }。但我得到:

sh-3.2# if [ $currPos -le $finalStep ]; then {hexdump -n $stepSize -Cv -s $currPos /dev/disk0s1;currPos=$(($currPos + $stepSize));echo $currPos;}; else break; fi
sh: syntax error near unexpected token `}'

我該怎麼做?,如何解決這個問題(不採用變數的更新值)?

編輯 2 Stéphane-Chazelas幫助了我!(閱讀關於{ and 的評論,分別注意 of 之後和之前 }的空格)。{``}

sh-3.2# currPos=0;stepSize=16;finalStep=48;
sh-3.2# if [ $currPos -le $finalStep ]; then { hexdump -n $stepSize -Cv -s $currPos /dev/disk0s1;currPos=$(($currPos + $stepSize));echo $currPos; }; else break; fi
00000000  8d 1c 09 48 65 8c 3c 6e  01 00 00 00 00 00 00 00  |...He.<n........|
00000010
16
sh-3.2# if [ $currPos -le $finalStep ]; then { hexdump -n $stepSize -Cv -s $currPos /dev/disk0s1;currPos=$(($currPos + $stepSize));echo $currPos; }; else break; fi
00000010  bd 04 00 00 00 00 00 00  01 00 00 80 00 00 00 00  |................|
00000020
32
sh-3.2# if [ $currPos -le $finalStep ]; then { hexdump -n $stepSize -Cv -s $currPos /dev/disk0s1;currPos=$(($currPos + $stepSize));echo $currPos; }; else break; fi
00000020  4e 58 53 42 00 10 00 00  00 f4 01 00 00 00 00 00  |NXSB............|
00000030
48
sh-3.2# if [ $currPos -le $finalStep ]; then { hexdump -n $stepSize -Cv -s $currPos /dev/disk0s1;currPos=$(($currPos + $stepSize));echo $currPos; }; else break; fi
00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000040
64
sh-3.2# if [ $currPos -le $finalStep ]; then { hexdump -n $stepSize -Cv -s $currPos /dev/disk0s1;currPos=$(($currPos + $stepSize));echo $currPos; }; else break; fi
sh-3.2# 

測試分號(靠近else break):

sh-3.2# if [ $currPos -le $finalStep ]; then { hexdump -n $stepSize -Cv -s $currPos /dev/disk0s1;currPos=$(($currPos + $stepSize));echo $currPos }; else break; fi
sh: syntax error near unexpected token `else'
sh-3.2# if [ $currPos -le $finalStep ]; then { hexdump -n $stepSize -Cv -s $currPos /dev/disk0s1;currPos=$(($currPos + $stepSize));echo $currPos; }; else break; fi
sh-3.2# if [ $currPos -le $finalStep ]; then { hexdump -n $stepSize -Cv -s $currPos /dev/disk0s1;currPos=$(($currPos + $stepSize));echo $currPos; } else break; fi
sh-3.2# 

主要問題是該選項應在操作數之前指定。一些 GNU 工具重新排列給定的參數,以便為方便起見(以便使用者不必考慮它),但hexdump在非 GNU 系統上不是執行此操作的工具之一。

因此,請按照手冊中的概要建議使用這些工具。這是來自 macOS 系統(FreeBSD 手冊的內容相同):

hexdump [-bcCdovx] [-e format_string] [-f format_file] [-n length]
       [-s offset] file ...

也就是說,像這樣重新排列命令行:

hexdump -n "$stepSize" -Cv -s "$currPos" /dev/disk0s1

如果您將選項放在文件名之後,然後將-n選項排除在外並hexdump繼續讀取其所有輸入,您最終會看到它會嘗試使用-s它的選項參數作為要讀取的文件名:

[...]
hexdump: -s: No such file or directory
hexdump: 12: No such file or directory

至於你問題的後半部分:

  • $currPos使用時,在命令呼叫之間不會更新in 的值,(...)因為您在顯式子shell 中更新它,即在括號內。無法從子shell 中更改父環境,並且子shell 環境在終止時會被丟棄。
  • 使用時{ ...; },後面需要有空格{。是引入“複合命令”的{關鍵字,即由幾個其他命令組成的命令。

在 shell 語法需要單個命令的情況下,您通常會使用這樣的複合命令,例如管道的單個階段,或者將多個命令的輸出與單個重定向一起重定向。

{ ...; }語句中的使用是不必要的,因為在你的語句中和(或)if之間可能有任意數量的單獨命令:then``else``fi``if

if [ "$currPos" -le "$finalStep" ]; then
   hexdump -n "$stepSize" -Cv -s "$currPos" /dev/disk0s1
   currPos=$((currPos + stepSize))
   printf '%s\n' "$currPos"
fi

請注意,這break僅用於跳出循環。

在一行上,這變成

if [ "$currPos" -le "$finalStep" ]; then hexdump -n "$stepSize" -Cv -s "$currPos" /dev/disk0s1; currPos=$((currPos + stepSize)); printf '%s\n' "$currPos"; fi

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