簡體   English   中英

Shell 參數擴展在 ksh 中工作,但在 bash 中不工作

[英]Shell parameter expansion working in ksh but not in bash

為什么下面的代碼在ksh和bash中產生不同的output

p="folderA/folderB/folderC"
echo ${p%%+([^/])}
echo ${p#${p%%+([^/])}}

ksh 輸出:

folderA/folderB/
folderC

bash 輸出:

folderA/folderB/folderC

我特別困惑,因為我使用了bash 文檔來創建這個參數擴展。

我想在最后一個斜杠之后提取文件夾名稱。 我發現了另一種在 ksh 和 bash 中工作的方法:

echo ${p##*/}

但我想了解為什么第一種方法不起作用。

+(...)是擴展 glob 語法,您需要為 bash 啟用extglob功能才能理解它。 另一個答案所述,通常不應使用抑揚符來否定字符 class。 Bash 可以容忍這個錯誤,但無論如何,為了可移植性,讓我們使用正確的語法:

shopt -s extglob
p="folderA/folderB/folderC"
echo "${p%%+([!/])}"
echo "${p#${p%%+([!/])}}"

產量:

folderA/folderB/
folderC

相關鏈接: Bash 參考手冊§模式匹配


順便說一句,您實際上並不需要擴展 glob。

p="folderA/folderB/folderC"
echo "${p%${p##*/}}"
echo "${p##*/}"

上面的腳本同樣適用於任何符合 POSIX 的 shell。

另一個更符合標准的 Korn shell 實際輸出

folderA/folderB/folderC

后跟一個空行。 這是因為 shell glob不是正則表達式,字符 class 協商運算符是假朋友。

在 POSIX shell 中, [^/] 實際上是未指定的,但通常( ["^"/]更清楚)表示“ ^/ ”,但您會想要“任何不是/的東西”,在 POSIX shell [!/][!/]代替。

有關 GNU bash 如何需要shopt -s extglob以另外支持 Korn shell 兼容的擴展通配模式的解釋,請參見其他答案

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM