私は今朝bashターミナルでこの奇妙な振る舞いをしました:
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
掘り下げた後、30番目の文字(client.confと "]"の間のスペース)を削除し、それをスペースに置き換えると、コマンドが再び動作します。
私の仮定は正しかった:不明な空白文字がコマンドに入力されましたが、質問は次のとおりです:
ところで、私はUbuntu 18.04 /フランス語を実行しています。コマンドを貼り付けるスクリプトはUSBドライブにあり、Windowsでも編集されている可能性があります。
非常に良い答えをありがとう。悪い文字はc2 a0の改行なしスペースUTF-8文字です。質問 sedで特殊な「M-BM-」文字を削除する方法 には、その文字について興味深い事実があります。
奇妙なことに、スクリプトにはこのキャラクターが含まれていません。どこから来たのかわかりません。
1つのオプションは、16進ビューアまたはエディタで使用しようとしている文字を確認することです。 hexdump
は、端末に制限がある場合に適したオプションです。
$ 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
space
、close-square-brace
、space
が正しいことがわかります-0x20
、0x5D
、0x20
。
これらの値はASCIIコード、 16進数 で表示されます。範囲外の値0x20
-0x7E
は "ではありません印刷可能な文字 " ASCIIに関する限り、コマンドラインインターフェイスではうまく機能しない可能性があります。
注:最初の "broken"行を上記のhexdump
の例で使用するためにコピーしたので、何かがnot-an-ASCII-spaceをASCII元のソースとレンダリングされた質問の間のスペースに置き換えました。
これを繰り返すには、次の手順を実行します。
hexdump -Cv <<"EOF"
と入力して押します EnterEOF
と入力し、 Enterターミナルとコマンドラインインターフェイスは、特殊文字を適切に処理しません-ご存じのとおりです。ドキュメントのフォーマットに細心の注意を払っていない場合は、Microsoft Word(およびその他)で「smart quotes」、em-dashesを使用すると問題が発生します。リストは続きます。 ..
違いを見つけます:(上部は「smart quotes」、下部は「straight quotes」)
$ 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
ここで、開いた引用は単純なASCII引用("
)ではありませんが、Unicode/ TF-8 シリーズ-0xE2
です、0x80
、0x9C
、または U+201C
-予想どおりに端末が処理しません。
Kiwyのcat -A
の提案も機能します。
$ cat -A <<"EOF"
> “quoted string”
> EOF
M-bM-^@M-^\quoted stringM-bM-^@M-^]$
注:echo "..." | hd
を使用すると、bashが検査しようとしているストリング。これは、スクリプトのコンポーネントを検査しようとするときに特に懸念されます。
たとえば、次のことを試してください。
$ echo "${USER}"
attie
$ echo "`whoami`"
attie
$ echo "$(whoami)"
attie
$ cat <<EOF
> ${USER}
> EOF
attie
これらのメソッドは、コンポーネントを関連するテキストに置き換えています。これを回避するには、次のいずれかの方法を使用します。単一引用符('
)と "quoted heredoc" ("EOF"
)の使用に注意してください。
$ echo '${USER}'
${USER}
$ echo '`whoami`'
`whoami`
$ echo '$(whoami)'
$(whoami)
$ cat <<"EOF"
> ${USER}
> EOF
${USER}
cat
と-A
オプション:マニュアルから:
-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
そう cat -A yourscrip.sh
は、目に見えない奇妙な文字を表示します。
echo "<your command>" | hd
は動作するはずです。バックスペース(0x08)またはコード> = 80の文字を探します。 echo "<your command>" | wc -b
とカウントがあなたが見るものと一致することをチェックすることも良い考えです。
名前に「Office」が付いているものから作成されたファイルからのものをコピーすることは危険です。そのようなソフトウェアは文字を置き換えるために自由をとる場合が多いためです。同等の開閉。私が見つけた中で最も難しいのは、ファイル名の中央にある幅0の改行しないスペース(3日間のサーバーのダウンタイム...)でした。
Bash、およびzshのような他のシェルは、現在のコマンドラインをエディターで開くことができます。 bashのデフォルトのショートカットはC-x C-e
(CtrlXCtrlE)、そして$VISUAL
、$EDITOR
、emacsの最初の利用可能な場所で開きます。実際には、これは複雑なコマンドのデバッグと変更に非常に役立ちます。見方によっては、zshの方がbashよりもフレンドリーです。エディターが終了すると、bashはすぐにコマンドを実行しますが、zshはユーザーが押すのを待ちます。 Enter (コマンドを編集する機会が増えます)。
エディターでコマンドを開いた後、非ASCII文字を別の方法で表示するようにエディターを構成できます。
たとえば、次の設定を使用して with Vim :
set encoding=latin1
set isprint=
set display+=uhex
または、他の回答の方法を適応させる:
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$