Arbeiten mit Dateinamen in einer anderen Codierung über ssh

8

Ich gehe zu einem Remote-System, auf dem eine andere Codierung für die Dateinamen (und für die Gebietsschemas der Benutzer) verwendet wurde. Und das verursacht einige Probleme.

Probleme, die durch Abgleichen der Ländereinstellungen behoben wurden

Bevor ich zu den Problemen mit Dateinamen übergehe, möchte ich sagen, dass einige Codierungsprobleme mit einer solchen SSH-Sitzung gelöst werden, indem das Remote-Gebietsschema so eingestellt wird, dass es mit dem lokalen Gebietsschema übereinstimmt , nämlich

  • die Probleme beim Bearbeiten der Befehlszeile (ich habe dreimal die Rücktaste gedrückt, aber da auf meinem Host die Codierung UTF-8 ist und auf der Remote-Seite - KOI8-R oder vielleicht CP1251, einige kyrillische 8-Bit-Codierungen, war dies nicht der Fall) t meine kyrillische Zeichenfolge nicht korrekt beeinflussen):

 

[imz@localhost ~]$ locale
LANG=ru_RU.UTF-8
LC_CTYPE="ru_RU.UTF-8"
LC_NUMERIC="ru_RU.UTF-8"
LC_TIME="ru_RU.UTF-8"
LC_COLLATE="ru_RU.UTF-8"
LC_MONETARY="ru_RU.UTF-8"
LC_MESSAGES="ru_RU.UTF-8"
LC_PAPER="ru_RU.UTF-8"
LC_NAME="ru_RU.UTF-8"
LC_ADDRESS="ru_RU.UTF-8"
LC_TELEPHONE="ru_RU.UTF-8"
LC_MEASUREMENT="ru_RU.UTF-8"
LC_IDENTIFICATION="ru_RU.UTF-8"
LC_ALL=
[imz@localhost ~]$ echo привет
привет
[imz@localhost ~]$ echo при
при
[imz@localhost ~]$ ssh -vv [email protected]
Last login: Fri Nov 25 13:44:56 2011 from NN.NN.NN.NN
[ivan@dell ~]$ locale
LANG=ru_RU.KOI8-R
LC_CTYPE="ru_RU.KOI8-R"
LC_NUMERIC="ru_RU.KOI8-R"
LC_TIME="ru_RU.KOI8-R"
LC_COLLATE="ru_RU.KOI8-R"
LC_MONETARY="ru_RU.KOI8-R"
LC_MESSAGES=POSIX
LC_PAPER="ru_RU.KOI8-R"
LC_NAME="ru_RU.KOI8-R"
LC_ADDRESS="ru_RU.KOI8-R"
LC_TELEPHONE="ru_RU.KOI8-R"
LC_MEASUREMENT="ru_RU.KOI8-R"
LC_IDENTIFICATION="ru_RU.KOI8-R"
LC_ALL=
[ivan@dell ~]$ echo привет
привет
[ivan@dell ~]$ echo при   
привÐ
[ivan@dell ~]$ export LANG=ru_RU.UTF-8
[ivan@dell ~]$ echo привет
привет
[ivan@dell ~]$ echo при
при
[ivan@dell ~]$ 
  • das Problem mit dem korrekten Verständnis der Groß- und Kleinschreibung für die verarbeiteten Zeichenfolgen; Jetzt würde es funktionieren, nachdem ich das Gebietsschema festgelegt habe:

 

[ivan@dell ~]$ echo привет | fgrep -i ВЕТ
привет
[ivan@dell ~]$ 

aber das würde vorher nicht funktionieren.

Kleinere Probleme mit Dateinamen

Die Dienstprogramme, die Dateinamen ausdrucken (die, wie Sie sich erinnern, remote in einer anderen Codierung gespeichert sind), würden sie nicht wörtlich drucken, aber sie setzen Fragezeichen für die Fremdzeichen ein:

[ivan@dell ~]$ find ~mama/Desktop/ -iname '*.xls'
/home/mama/Desktop/????????? ????????.xls
/home/mama/Desktop/???????? ??? ???????????? (1).xls
/home/mama/Desktop/???????? ??? ???????????? (2).xls
/home/mama/Desktop/???????? ??? ???????????? (3).xls
/home/mama/Desktop/???????? ??? ????????????.xls
[ivan@dell ~]$ find ~mama/Desktop/ -iname '*.xls' -print
/home/mama/Desktop/????????? ????????.xls
/home/mama/Desktop/???????? ??? ???????????? (1).xls
/home/mama/Desktop/???????? ??? ???????????? (2).xls
/home/mama/Desktop/???????? ??? ???????????? (3).xls
/home/mama/Desktop/???????? ??? ????????????.xls
[ivan@dell ~]$ 

Das gleiche Problem wird von lsund so weiter gezeigt. Dies kann jedoch leicht überwunden werden, indem sie als Zeichenfolgen an Druckbefehle übergeben werden (denen das Problem mit nicht übereinstimmenden Codierungen der Dateinamen und des Terminals nicht bekannt ist - oder aus welchem ​​Grund auch immer, aber es funktioniert):

[ivan@dell ~]$ find ~mama/Desktop/ -iname '*.xls' -print0 | xargs -0 -n 1 echo 
/home/mama/Desktop/Êðåäèòíûé ïîðòôåëü.xls
/home/mama/Desktop/ÀÄÐÅÑÀÒÛ äëÿ ïîçäðàâëåíèé (1).xls
/home/mama/Desktop/ÀÄÐÅÑÀÒÛ äëÿ ïîçäðàâëåíèé (2).xls
/home/mama/Desktop/ÀÄÐÅÑÀÒÛ äëÿ ïîçäðàâëåíèé (3).xls
/home/mama/Desktop/ÀÄÐÅÑÀÒÛ äëÿ ïîçäðàâëåíèé.xls
[ivan@dell ~]$ 

Auch die Tatsache, dass sie nicht lesbar sind, war nicht sehr ärgerlich, da ich | recode -f cp1251..utf-8am Ende des Befehls immer eine anhängen konnte .

Das nervige Problem

Das wesentliche Problem ist, dass das Auswählen (mit der Maus) der Dateinamen im Terminal und das Einfügen nicht funktioniert:

[ivan@dell ~]$ diff '/home/mama/Desktop/ÀÄÐÅÑÀÒÛ äëÿ ïîçäðàâëåíèé (1).xls' '/home/mama/Desktop/ÀÄÐÅÑÀÒÛ äëÿ ïîçäðàâëåíèé (3).xls'
diff: /home/mama/Desktop/ÀÄÐÅÑÀÒÛ äëÿ ïîçäðàâëåíèé (1).xls: No such file or directory
diff: /home/mama/Desktop/ÀÄÐÅÑÀÒÛ äëÿ ïîçäðàâëåíèé (3).xls: No such file or directory
[ivan@dell ~]$ 

Ich habe eine maskierte Darstellung der Dateinamen in der Ausgabe von bemerkt stat, sodass ich sie auswählen und einfügen konnte (innen $''in Bash ):

[ivan@dell ~]$ diff '/home/mama/Desktop/\300\304\320\305\321\300\322\333 \344\353\377 \357\356\347\344\360\340\342\353\345\355\350\351 (1).xls' '/home/mama/Desktop/\300\304\320\305\321\300\322\333 \344\353\377 \357\356\347\344\360\340\342\353\345\355\350\351 (3).xls'
diff: /home/mama/Desktop/\300\304\320\305\321\300\322\333 \344\353\377 \357\356\347\344\360\340\342\353\345\355\350\351 (1).xls: No such file or directory
diff: /home/mama/Desktop/\300\304\320\305\321\300\322\333 \344\353\377 \357\356\347\344\360\340\342\353\345\355\350\351 (3).xls: No such file or directory
[ivan@dell ~]$ diff $'/home/mama/Desktop/\300\304\320\305\321\300\322\333 \344\353\377 \357\356\347\344\360\340\342\353\345\355\350\351 (1).xls' $'/home/mama/Desktop/\300\304\320\305\321\300\322\333 \344\353\377 \357\356\347\344\360\340\342\353\345\355\350\351 (3).xls'
Files /home/mama/Desktop/ÀÄÐÅÑÀÒÛ äëÿ ïîçäðàâëåíèé (1).xls and /home/mama/Desktop/ÀÄÐÅÑÀÒÛ äëÿ ïîçäðàâëåíèé (3).xls differ
[ivan@dell ~]$ 

Die Frage ist also:

Wie arbeite ich bequem mit entfernten Dateinamen (über ssh ), die sich in einer anderen Codierung befinden?

Es wäre schön, wenn sie lesbar und auswählbar und einfügbar wären (und auch von mir über die Tastatur eingegeben und dann von Tab in Bash vervollständigt werden können; um von mir bequem eingegeben werden zu können, müssen sie natürlich lesbar sein).

Ich arbeite in urxvt in X.org unter Linux auf dem lokalen Host und es ist Bash unter Linux am Remote-Ende.

imz - Ivan Zakharyaschev
quelle

Antworten:

4

In einem Terminalemulator, der UTF-8 unterstützt, können Sie mit dem luitBefehl eine Subshell (oder ein anderes Programm) in einem anderen Gebietsschema ausführen. Die Gebietsschemaeinstellung, die Zeichensätze angibt, ist LC_CTYPE.

LC_CTYPE=ru_RU.KOI8-R luit ls   # run one command
LC_CTYPE=ru_RU.KOI8-R luit      # start a shell (type Ctrl+D or exit to return to the parent shell)

Wenn Sie einen ganzen Baum von Dateien in einer anderen Codierung haben, empfehle ich (wenn möglich), ihn über convmvfs zu mounten .

mkdir ~/net/[email protected] ~/net/[email protected]
sshfs [email protected]: ~/net/[email protected]
convmvfs -o srcdir=~/net/[email protected],icharset=KOI8-R,ocharset=UTF-8 ~/net/[email protected]
ls ~/net/[email protected]
Gilles 'SO - hör auf böse zu sein'
quelle
3

Wahrscheinlich könnte man in Betracht ziehen, einige komplexe Terminalemulatoren wie screen (an beiden Enden) zu verwenden, die die Zeichen übersetzen (oder eine Übersetzungserweiterung in ssh ... verwenden), oder man könnte eine convmvfs- Ansicht des Dateisystems remote einrichten (mit Dateinamen, die in die lokale Codierung umcodiert wurden), aber es gibt eine einfache Lösung:

Erstellen Sie einfach eine "Umgebung" auf dem lokalen Host, speziell für die Arbeit mit diesem Remote-Host, und arbeiten Sie in dieser Umgebung (führen Sie ssh usw. aus). Starten Sie in der Situation, in der sich die Remote-Dateinamen in CP1251 befinden, ein neues Terminal in X. das würde mit dieser Codierung funktionieren :

$ LC_CTYPE=ru_RU.CP1251 xvt &

und arbeite daraus. (Wenn Sie die Linux-Konsole mehr als X mögen, könnten Sie wahrscheinlich eine virtuelle Linux-Konsole entsprechend einrichten, aber das Wissen über das Einrichten der Linux-Konsole ist aus meinem Kopf verschwunden ...)

imz - Ivan Zakharyaschev
quelle
1
Nicht festlegen LC_ALL, das ist die Notfallüberschreibung für Gebietsschemas. Festlegen, LANGob Sie einen Standard für alle Kategorien festlegen möchten, oder die genaue Kategorie festlegen, an der Sie interessiert sind, z. B. LC_CTYPEfür den Zeichensatz und die Codierung.
Gilles 'SO - hör auf böse zu sein'