Bir bash komut dizesinin kelimesi kelimelerini nasıl kontrol edebilirim?


15

Bu sabah bir bash terminalinde bu garip davranışı yaşadım:

user@home:/home/user$ [ -f /etc/openvpn/client.conf ] && echo true
bash: [: missing «]»
user@home:/home/user$ [ -f /etc/openvpn/client.conf ] && echo true
true
  • İlk komut gedit ile düzenlenen bir komut dosyasından yapıştırıldı .
  • İkincisi doğrudan terminale yazılmıştır .

Biraz kazmadan sonra , 30. karakteri (client.conf ve "]" arasındaki boşluk) kaldırmanın ve bir boşlukla değiştirmenin komutun tekrar çalışmasını sağladığını öğrendim.

Benim varsayım haklıydı: bilinmeyen bir boş karakter komuta girdi , ancak soru şu:

  1. Komutta hata ayıklamak için terminaldeki bu karakterleri nasıl gösterebilirim? Ve daha da önemlisi:
  2. Bunun tekrar olmasını nasıl önleyebilirim?

BTW, Ubuntu 18.04 / Fransızca dilini çalıştırıyorum, komutu yapıştırdığım komut dosyası bir USB sürücüsünde ve Windows'ta da düzenlenmiş olabilir.


Çok iyi cevaplarınız için teşekkür ederim. Kötü karakter bir c2 a0 kırılmaz boşluk UTF-8 karakteridir. Sed ile özel 'M-BM-' karakterini kaldırma sorusu bu karakter hakkında ilginç bir gerçeğe sahiptir.

Garip olan şey, betiğin bu karakterden arınmış olmasıdır. Bu yüzden nereden geldiğini bilmiyorum.


3
Bu karakterleri vurgulayan bir düzenleyici kullanın. Sözdizimi vurgulama da çok yardımcı olur. Asla doğrudan web'den terminale yapıştırmayın, her zaman yukarıda belirtilen editörden geçin.
choroba

2
Geçmiş listenizdeki problem komutunu bulmak, ardından çıktıyı bir onaltılık görüntüleme programı aracılığıyla iletmek isteyebilirsiniz. Uzun bir listeye girmenize gerek kalmaması için ya geçmişi listenin en altına yerleştirmek için komutu yeniden çalıştırın ve çalıştırın history 2|xxd(çünkü historykomutun kendisi her zaman listede sonuncudur) veya yazın history|grep "CommandWithProblem"|xxd. Bunun yerine başka bir hex görüntüleme programı kullanabilirsiniz xxd, ancak bu varsayılan olarak sevdiğim bir biçimdir.
AFH

@Gabriel Glenn, en iyi / en yararlı / ne olursa olsun cevabı kene işaretini kullanarak " kabul edilmiş " olarak işaretleyin. bilgisi
Attie

1
@Attie, Evet, en iyi cevapları kabul etmeden önce genellikle 24 saat bekleyeceğim, önerildiği gibi: meta.stackexchange.com/questions/5234/…
Gabriel Glenn

1
Şahsen ben kullanardım set -x. Bu size komutu ve nasıl bölündüğünü gösterir. Mutlaka "burada kötü karakter" demek değildir, ama size bash'ın bu karakter üzerinde bölünmediğini gösterir.
Patrick

Yanıtlar:


11

Seçeneklerden biri onaltılık görüntüleyici veya düzenleyici ile kullanmaya çalıştığınız karakterlere bakmaktır. hexdumpterminalle sınırlıysanız iyi bir seçenektir.

$ hexdump -Cv <<"EOF"
> [ -f /etc/openvpn/client.conf ] && echo true
> EOF
00000000  5b 20 2d 66 20 2f 65 74  63 2f 6f 70 65 6e 76 70  |[ -f /etc/openvp|
00000010  6e 2f 63 6c 69 65 6e 74  2e 63 6f 6e 66 20 5d 20  |n/client.conf ] |
00000020  26 26 20 65 63 68 6f 20  74 72 75 65 0a           |&& echo true.|
0000002d

Bunu burada görebilirsiniz space, close-square-brace, spacedoğru - 0x20, 0x5D, 0x20.

Bu değerler, onaltılı olarak görüntülenen ASCII kodlarıdır . Aralığının dışında herhangi bir değer 0x20- 0x7Ebir değil " yazdırılabilir karakter " ASCII ilgilidir ve büyük olasılıkla komut satırı arayüzlerle de çalmıyor kadarıyla.

Not: Ben ilk "kopyalanmış kırık kullanılmak üzere" satırı hexdumpşey yerini böylece, yukarıdaki örnekte değil-bir-ASCII boşluk orijinal kaynağından ve render soruya arasında bir ASCII boşluk.


Bunu tekrarlamak için aşağıdaki adımları uygulayın:

  1. Yazın hexdump -Cv <<"EOF"ve basınEnter
  2. Kullanmak istediğiniz metni yapıştırın
  3. Tür EOFkendine ait bir çizgi üzerinde ve basınEnter

Terminaller ve Komut Satırı Arayüzleri, keşfettiğiniz gibi özel karakterleri iyi işlemez. Belgeleri biçimlendirmeye çok dikkat etmezseniz, " akıllı tırnaklar ", em-tire kullanarak Microsoft Word (ve diğerleri) ile de sorunlarınız olacak , liste devam ediyor ...

Farkı bulun: (üst " akıllı tırnak ", alt " düz tırnak ")

akıllı tırnak örneği ile düz tırnak örneği

$ hexdump -Cv <<"EOF"
> quoted string
> EOF
00000000  e2 80 9c 71 75 6f 74 65  64 20 73 74 72 69 6e 67  |...quoted string|
00000010  e2 80 9d 0a                                       |....|
00000014

Burada, açık tırnak basit bir ASCII alıntı (değil "), fakat bir Unicode / vardır UTF-8 serisi - 0xE2, 0x80, 0x9Cveya U+201C- Tahmin edebileceğiniz gibi terminal işlemez hangi.

Kiwy'nin önerisi cat -Ade işi yapar:

$ cat -A <<"EOF"
> quoted string
> EOF
M-bM-^@M-^\quoted stringM-bM-^@M-^]$

Not: kullanırkenecho "..." | hd, bash'ın incelemeye çalıştığınız dizenin bölümlerini değiştirme şansı vardır. Bu, bir betiğin bileşenlerini incelemeye çalışırken özellikle endişe vericidir.

Örneğin şunu deneyin:

$ echo "${USER}"
attie

$ echo "`whoami`"
attie

$ echo "$(whoami)"
attie

$ cat <<EOF
> ${USER}
> EOF
attie

Bu yöntemler, bileşenleri ilgili metinle değiştirmektir. Bundan kaçınmak için aşağıdaki yaklaşımlardan birini kullanın. Tek tırnak işareti ( ') ve bir " alıntılanmış yorumlu metin " ( "EOF") kullanıldığına dikkat edin.

$ echo '${USER}'
${USER}

$ echo '`whoami`'
`whoami`

$ echo '$(whoami)'
$(whoami)

$ cat <<"EOF"
> ${USER}
> EOF
${USER}

Bu çözüm işe yarar: echo "[ -f /etc/openvpn.ovpn ]" | hd döner [...] c2 a0 [...]. Biz görebilirsiniz c2 a0 UT-8 karakter olmayan kırma boşluk
Gabriel Glenn

18

Sen kullanabilirsiniz catile -Aseçeneği: manuel den:

   -A, --show-all
          equivalent to -vET
   -E, --show-ends
          display $ at end of each line
   -T, --show-tabs
          display TAB characters as ^I
   -v, --show-nonprinting
          use ^ and M- notation, except for LFD and TAB

Yani cat -A yourscrip.shsize görünmez ve garip karakterler gösterecektir.


7
Bu çözüm işe yarar: echo "[ -f /etc/openvpn.ovpn ]" | cat -Adöner [ -f /etc/openvpn/client.ovpnM-BM- ]$. Biz görebilirsiniz M-BM- UT-8 karakter olmayan kırma boşluk
Gabriel Glenn

@GabrielGlenn bunun size yardımcı olduğuna sevindim.
Kiwy

9

echo "<your command>" | hdçalışmalı. Geri tuşu (0x08) veya> = 80 kodlu karakterleri arayın. echo "<your command>" | wc -bve sayının gördüğünüzle eşleştiğini kontrol etmek de iyi bir fikirdir.

Adında "Office" ile herhangi bir şey tarafından üretilen dosyalardan bir şeyler kopyalamak tehlikelidir, çünkü bu tür yazılımlar genellikle karakterleri değiştirme özgürlüğünü alır: Fransızca'da, "guillemets" ile değiştirilen çift tırnaklara, İngilizce ile değiştirilen düz tırnaklar için açık / kapalı eşdeğerleri. Şimdiye kadar bulduğum en zor olanı, bir dosya adının ortasında (3 günlük sunucu kapalı kalma süresi ...) 0 genişliğinde kırılmayan bir boşluktu.


2
Attie'nin cevabında da belirtildiği hdiçin kısaca bahsetmeye değer hexdump.
Mikael Kjær

@ MikaelKjær - Ubuntu'da, hdeşdeğerdir hexdump -C.
AFH

1
@xenoid: 'Windows'ta düzenlendi' dedim, bir Office Writer ile düzenlenmedi, deli değiliz;). Düzenlenmişse, Notepad ++ ile yapıldı.
Gabriel Glenn

1
Bu çözüm işe yarar: echo "[ -f /etc/openvpn.ovpn ]" | hd döner [...] c2 a0 [...]. Biz görebilirsiniz c2 a0 UT-8 karakter olmayan kırma boşluk
Gabriel Glenn

2

Bash ve zsh gibi diğer kabuklar, geçerli komut satırını bir düzenleyicide açabilir. Bash için varsayılan kısayol olan C-x C-e( CtrlX CtrlE) ve ilk kullanılabilir açılır $VISUAL, $EDITORve emacs. Uygulamada bu, karmaşık komutların hatalarını ayıklamak ve değiştirmek için paha biçilmezdir. Nasıl baktığınıza bağlı olarak, zsh burada bash'den daha dostudur: editör çıktığı zaman bash komutu hemen çalıştırırken, zsh basmanızı beklerEnter (komutu düzenlemek için daha fazla şans verir).

Komutu bir düzenleyicide açtıktan sonra, editörlerinizi ASCII olmayan karakterleri farklı gösterecek şekilde yapılandırabilirsiniz.

Örneğin, Vim ile şu ayarları kullanarak:

set encoding=latin1
set isprint=
set display+=uhex

resim açıklamasını buraya girin

Veya diğer cevapların yöntemlerini uyarlamak:

bash-4.4$ f() { cat -A "$@"; false; }   # exit false to prevent bash from running the command
bash-4.4$ VISUAL=f
bash-4.4$ [ -f /etc/openvpn/client.conf ] && echo true  # C-x C-e here
[ -f /etc/openvpn/client.confM-BM- ] && echo true$
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.