18936


Linux/BSD初心者です。

`Ubuntu15.04`の`GNOME端末`より、リモートホストの`CentOS6.7`にログインすると

[code]

    $ echo 'あいうえお'
    あいうえお
    
[/code]

と行うことができます。

同じことを`FreeBSD10.2-stable`で行うと

'あいうえお'と入力して`Enter`を押した瞬間にそれまでの入力文字が全て消去されてしまいました。何も入力しなかったかのようになります。  
より正確に言うと、(`Ubuntu`の`GNOME端末`上で)「`echo`
」と入力後、`Mozc`にて日本語変換モードで「`あいうえお`」と入力まで行い、それから`Enter`を押すと、「echo」と入力した部分も含めて全部バックスペースで消されるような動作をします。

[code]

    $echo 'あいうえお'
    $
    
[/code]

`BSD`のシェルは`sh(ash)`, `CentOS`は`bash`です。デフォルトから変えていません。  
`LANG`は共に`ja_JP.UTF-8`です。

また`CentOS`, `FreeBSD`共に日本語の書かれたファイルを`cat`で表示すると問題なく表示できます。

`FreeBSD`の`man`で`sh`のページを調べると、その末尾に`UTF8`以外のマルチバイト文字はサポートしないと書かれていました。逆に言えば`UTF8`ならサポートすると解釈できるのですが、これは出力のみサポートという意味なのでしょうか。そんな半端なことはしないような気がするのですが、どういう仕組みで動いているのかわからないので全て想像の域を出ません。

同じ端末からの入力なので`CentOS`に対しても`FreeBSD`に対しても同じ電文を送っていると思います。ロケールも揃え、出力に関しては同じ挙動をするのに入力については違う挙動を行うというのは、どういう仕様/設定の違いからくるものなのでしょうか？
ご存じの方ご教示おねがいします。

* * *

追記  
`stty -a` の結果比較は次のようになりました。

  1. CentOS

$ stty -a  
speed 38400 baud; rows 39; columns 146; line = 0;  
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = M-^?; eol2 =
M-^?; swtch = ; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;  
werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;  
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts -cdtrdsr  
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc ixany imaxbel -iutf8  
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0
ff0  
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke

  2. FreeBSD

$ stty -a  
speed 38400 baud; 39 rows; 146 columns;  
lflags: icanon isig iexten echo echoe echok echoke -echonl echoctl  
-echoprt -altwerase -noflsh -tostop -flusho -pendin -nokerninfo  
-extproc  
iflags: -istrip icrnl -inlcr -igncr ixon -ixoff ixany imaxbel -ignbrk  
brkint -inpck -ignpar -parmrk  
oflags: opost onlcr -ocrnl tab0 -onocr -onlret  
cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow  
-dtrflow -mdmbuf  
cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = ;  
eol2 = ; erase = ^?; erase2 = ^H; intr = ^C; kill = ^U;  
lnext = ^V; min = 1; quit = ^\; reprint = ^R; start = ^Q;  
status = ^T; stop = ^S; susp = ^Z; time = 0; werase = ^W;


CC BY-SA 3.0
2015-11-15T22:20:37.813
18859
2015-11-19T07:49:54.193
2015-11-19T07:49:54.193
8000
9403
question
linux unicode freebsd
同じロケールでも日本語入力の可否に差がある理由


当初は tty の設定の問題かな？と思ったのですが違うようです。

まず最初に、`FreeBSD + bash` の場合でも同様の現象になります。

[code]

    $ uname -rs
    FreeBSD 10.2-RELEASE
    $ bash --version
    GNU bash, version 4.3.42(0)-release
    
    $ echo 'あいうえお'
    $ 
    
[/code]

bash の場合は readline ライブラリを利用していますので、`$HOME/.inputrc` を用意することで UTF-8
文字列を正常に入力することが可能になります。実際には 8 ビット目(MSB)が `1`
にセットされている「文字」をそのままの状態で扱います(いわゆる「8-bit スルー」)。

[code]

    ## .inputrc
    set input-meta on
    set convert-meta off
    set output-meta on
    
[/code]

> **readline(3)**
>
> **input-meta (Off)**
>
> If set to On, readline will enable eight-bit input (that is, it will not
> clear the eighth bit in the characters it reads), regardless of what the
> terminal claims it can support. The name meta-flag is a synonym for this
> variable.
>
> **convert-meta (On)**
>
> If set to On, readline will convert characters with the eighth bit set to an
> ASCII key sequence by stripping the eighth bit and prefixing it with an
> escape character (in effect, using escape as the meta prefix).
>
> **output-meta (Off)**
>
> If set to On, readline will display characters with the eighth bit set
> directly rather than as a meta-prefixed escape sequence.
[code]

    … 再度ログインしてから …
    $ echo 'あいうえお'
    あいうえお
    
[/code]

一方、FreeBSD の `/bin/sh` ですが、readline ライブラリを利用していません。それでは、ということで
`/etc/login.conf` に `charset` と `lang` を追加してみます。

[code]

    default:\
       :
            :charset=UTF-8:\
            :lang=ja_JP.UTF-8:
    
[/code]

DB を作成し直します。

[code]

    # /usr/bin/cap_mkdb /etc/login.conf
    
[/code]

ログインし直して試してみましたが、同じ現象のままです。なお、`/etc/login.conf` を変更した場合、bash であれば `.inputrc`
が無くても UTF-8 文字列の正常な入力が可能です。

最終的に `/bin/sh` のソースコードを眺めてみますと、いわゆる `8-bit` 文字は他の事に使われています。

[code]

    $ set +o emacs; set +o vi  # Disable line editing feature
    $ echo 'あいうえお'
    あいうえお
    
    $ set -o vi     # Enable vi mode
    $ echo 'あいうえお  <= 「お」を入力して Enter キーを押すと、以下の様に表示されます
    $ echo '\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212'
    あいうえお          <= 表示は正常
    
[/code]

`/bin/sh` は内部に readline と同様の行編集機能を持っています。その機能には emacs モードと vi モードがあり、emacs
モードでは、いわゆる `8-bit` 文字(の一部)が行編集機能を呼び出すコントロール・シーケンスとして認識されている、という事の様です。vi
モードではコントロール・シーケンスが `Escape キー(0x1b)`
のみであるため問題はないはずなのですが、表示がバイト列になっています。行編集機能が有効になっている場合、`/bin/sh`
内部では行の内容をバイト単位で扱っている事が原因の様です(はっきりと確認したわけではないので間違っているかもしれません)。

以上の様に行編集機能を無効にすれば良いのですが、、、行編集機能のないシェルはとても使いづらいですね。。。`csh` や `bash`
を使われることをお勧めしておきます。


CC BY-SA 3.0
2015-11-17T06:04:37.993
18936
2015-11-17T06:04:37.993
18859
answer


<https://en.wikipedia.org/wiki/Comparison_of_command_shells>  
を見ると、Unicodeのサポートは部分的("Partial")となっているので、`ash` で Unicode
を使うのは避けておくのが無難ではないかと思います。


CC BY-SA 3.0
2015-11-17T07:18:13.743
18938
2015-11-17T07:18:13.743
2521
18859
answer