Bash

grep 在 bash 腳本中有效,但在終端中無效

  • November 4, 2016

我的終端有一個奇怪的行為。

以下命令不會向我的終端列印任何內容:

comment=$(
   cat /usr/share/applications/brasero.desktop | 
   grep '^Comment=' |
   grep -Po '(?<=^Comment=)[ --0-9A-Za-z/.]*'
)
echo $comment

完全相同的命令,相同的語法在 bash 腳本中完美執行。

通常,我看到人們抱怨相反的行為。

我知道上面的操作可以通過數百種方式完成,但我不明白為什麼上面的命令沒有在我的終端中執行。

另一方面,這些命令在終端和腳本中都可以正常工作:

comment=$(
   cat /usr/share/applications/brasero.desktop |
   grep -Po '(?<=^Comment=)[ --0-9A-Za-z/.]*'
)
echo $comment

grep -Po '(?<=Exec=)[ --0-9A-Za-z/:space:]*' > /usr/share/applications/brasero.desktop

我在 Debian 8 Sid 下使用 GNU bash 版本 4.4.0(1)-release (x86_64-pc-linux-gnu) 和 grep (GNU grep) 2.26。我在 xfce 和 mate 終端中都嘗試過,但行為相同。

謝謝

當你遇到這樣的問題時,你應該開始從你的測試中刪除一些東西,直到你得到一些有用的東西。

例如,如果您的出發點是:

comment=$(cat /usr/share/applications/brasero.desktop |grep '^Comment=' |grep -Po '(?<=^Comment=)[ --0-9A-Za-z/.]*');echo $comment

首先去掉變數的東西:

cat /usr/share/applications/brasero.desktop |grep '^Comment=' |grep -Po '(?<=^Comment=)[ --0-9A-Za-z/.]*'

然後剝離第二個grep

cat /usr/share/applications/brasero.desktop |grep '^Comment='

然後另一個grep:

cat /usr/share/applications/brasero.desktop

最終你會發現它開始工作的地方。在您的特定情況下,它將開始使用:

cat /usr/share/applications/brasero.desktop |grep '^Comment='

所以grep這是一個問題。添加其他東西,看看它是否仍然有效:

comment=$(cat /usr/share/applications/brasero.desktop |grep '^Comment=');echo $comment

確實如此。所以有什麼問題?好吧,注意最後一個,輸出是彩色的嗎?輸出中包含 ANSI 顏色轉義碼。這阻止了第二個grep匹配。

修復方法是將您的grep別名更改為--color=auto或 dounalias grep或手動添加--color=never到命令中。


還有另一種方法可以解決這個問題。由於您知道它可以在腳本中工作,因此唯一的解釋是它是環境的。

因此,您可以從一個乾淨的環境bash --noprofile --norc開始,然後開始逐步引入您的個人資料,直到它崩潰。

不過,這種技術有一個問題。即使使用--noprofile --norc,CLI 和腳本之間也存在一些差異,例如歷史擴展和作業控制。不過,您也可以將其關閉:set +Hset -m.

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