Boş dizeyle sonuçlanan parametre genişletmesi farklı şekilde ele alınır


10

Güncelleme

Biri hata bash posta listesinde olan doğruladı bu bir hatadır.


Eğer ilgilenen varsa , son geliştirme devel şubesinde bir düzeltme mevcuttur .


Süre

bash -c 'echo "${1##*""}"' _ bar

boş bir satır yazdırır,

bash -c 'echo "${1##*"${1##*}"}"' _ bar

yazdırır bar.

Bunu anlamıyorum. ${1##*}boş bir dizeye genişler, bu yüzden "${1##*}"olduğu gibi ele alınmalıdır "", ama bash öyle düşünmüyor gibi görünüyor.

Diğer popüler shuygulamalar arasında bu konuda bir fikir birliği var gibi görünüyor :

$ sh -c 'echo "${1##*"${1##*}"}"' _ bar

$ ash -c 'echo "${1##*"${1##*}"}"' _ bar

$ dash -c 'echo "${1##*"${1##*}"}"' _ bar

$ ksh -c 'echo "${1##*"${1##*}"}"' _ bar

$ ksh93 -c 'echo "${1##*"${1##*}"}"' _ bar

$ mksh -c 'echo "${1##*"${1##*}"}"' _ bar

$ posh -c 'echo "${1##*"${1##*}"}"' _ bar

$ yash -c 'echo "${1##*"${1##*}"}"' _ bar

$ zsh -c 'echo "${1##*"${1##*}"}"' _ bar

$

bash (olsun veya olmasın --posix) buna uymayan tek kişi:

$ bash -c 'echo "${1##*"${1##*}"}"' _ bar
bar

Ve alt dize işleme şeyleri olmadan davranış beklendiği gibi olur:

$ bash -c 'echo "${1##*"${1+}"}"' _ bar

$ bash -c 'echo "${1##*"${2}"}"' _ bar

$ bash -c 'echo "${1##*"${2}"}"' _ bar ''

$ 

Kılavuzda bulamadığım bir açıklama olup olmadığını gerçekten merak ediyorum. Bu bir hata mı yoksa standardın yanlış yorumlanması mı? Bu davranış bir yerde belgelenmiş mi?


Not: Hızlı bir çözümün iç PE'yi ayırmak olduğunu biliyorum, ancak bu sorumu cevaplamıyor ve özel karakterler içeren dizelerle istenmeyen sonuçlara yol açabilir.


GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)boş bir dize yazdırır
William Pursell

GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)"bar" yazdırır
William Pursell

@William 4.4.20 ve 5.0.11'de test edildi ve her ikisi de "bar" yazdı
Oğuz İsmail

Bu genel olarak genişleme ile ilgili bir sorun gibi görünüyor. Benim 4.4.12(3)-release, echo "${BASH##*"${BASH##*}"}"-> /bin/bash. İken echo "\${BASH##*"${BASH##*}"}"-> ${BASH##*}ve eval echo "\${BASH##*"${BASH##*}"}"-> boş.
Jeff Y

Yanıtlar:


2

Bu bir cevap değil

İlk olarak bunun özel glob kurallarından kaynaklandığını düşünüyordum, ama sonunda bunun bash'da bir hata olduğunu düşünüyorum. Aşağıdaki dört örnek size bunun neden bir hata olduğuna inandığımı hissettirmelidir:

$ bash -c 'echo "${1##*${1%%bar}}"' _ foobar        # case 1
bar
$ bash -c 'echo "${1##*${1%%foobar}}"' _ foobar     # case 2

$ bash -c 'echo "${1##*"${1%%bar}"}"' _ foobar      # case 3
bar
$ bash -c 'echo "${1##*"${1%%foobar}"}"' _ foobar   # case 4
foobar

Vaka 1 ve vaka 3 tırnak içinde farklıdır. Ancak formun parametre genişletmesi, ${parameter##word}işlemek için pathname genişletme kurallarını kullanır word. Yani *foove *"foo"onlar özel desen karakterleri kucaklayan sürece dosyayolu çift tırnak olarak özdeş davranış göz ardı edilebilir olması ( *, ?, ...). Bu, aşağıdaki örnekte görülmektedir:

$ bash -c 'echo "${1##*${2%%b*r}}"' _ 'foobar' 'f*ob*r'
bar
$ bash -c 'echo "${1##*"${2%%b*r}"}"' _ 'foobar' 'f*ob*r'
foobar

Öyleyse, durum buysa, Durum 2 ve Durum 4 neden farklı davranmalıdır?


Durum 2 ve Durum 4 neden farklı davranmalıdır? Sebebi yok, hem ${1+}ve${1+""} genişlediğinde dize boşaltmak için, ancak yolu kabul edilmediği ${1##*}(benim en son düzenlemeyi bakınız). Böylece bunun bir hata olduğunu çıkarabiliriz, değil mi?
oguz ismail

1
@oguzismail Kesinlikle! Durum 1 ve durum 3 aynı davranırsa, durum 2 ve durum 4 de aynı şekilde davranmalıdır.
kvantour
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.