การเข้ารหัสผิดขณะเรียกเชลล์


9

ฉันกำลังทดลองกับไดอะแกรม DOT และพยายามทำสิ่งต่อไปนี้:

:! dot -Tpng -oFab.png %

ฉันพบข้อผิดพลาดเนื่องจากชื่อไฟล์ของฉันมีอักขระพิเศษ (" ó" ใน "Fabricación"):

C:\windows\system32\cmd.exe /c ( dot -Tpng -oFab.png Fabricaci├│n.gv)
Error: dot: can't open Fabricaci├│n.gv
shell returned 2
Hit any key to close this window...

อย่างที่คุณเห็นตัวละครพิเศษกำลังถูกเปลี่ยนเป็น " ├│" นี้จะมีเป็นกลุ่มและ gVim 7.4 ภายใต้ Win7 และ NTFS ดังนั้นผมถือว่าชื่อไฟล์ที่อยู่ในUTF16 ฉันยังคิดว่าเมื่ออัญเชิญเปลือก / cmd ชื่อไฟล์จะถูกตีความว่าเป็นบางเข้ารหัสอื่น ๆ (ขอบคุณCarpetsmokerสำหรับการชี้ออกเป็นค่าเริ่มต้นรหัสหน้า 850 )

ฉันจะแก้ไขสิ่งนี้ได้อย่างไร

แน่นอนว่าฉันสามารถเปลี่ยนชื่อไฟล์ได้ แต่ฉันอยากรู้ว่าทำไมสิ่งนี้ถึงเกิดขึ้นและวิธีแก้ไขไฟล์

อัปเดต : ฉันเพิ่งพบคำถามนี้ใน superuser.SE (ขอบคุณคำติชมจาก @ ChristianBrabandt ) แต่ดูเหมือนจะไม่ช่วยอะไรเช่นกัน


1
ฉันอยากรู้ว่าคุณจะได้รับข้อผิดพลาดเดียวกันโดยใช้ Vim บนบรรทัดคำสั่งภายใต้ Cygwin หรือ MobaXterm (สภาพแวดล้อมคล้าย Unix พกพาสำหรับ Windows) ฉันไม่สงสัย อาจมีวิธีแก้ไขปัญหานี้จริง ๆเพื่อให้ Windows cmdยอมรับชื่อไฟล์ แต่การได้รับสภาพแวดล้อมที่คล้าย Unix จะเป็นการจัดการที่ฉันต้องการ
ไวด์การ์ด

2
จากสิ่งที่ฉันอ่านเริ่มต้นสำหรับการcmd.exeไม่ได้เป็น Unicode แต่หน้ารหัส 850 ดูคำตอบนี้ด้วย
Martin Tournoij

ขอบคุณ @Carpetsmoker ฉันใช้เสรีภาพในการอัปเดตคำถามของฉันพร้อมข้อมูลที่คุณให้ไว้
Roflo

ฉันไม่แน่ใจอย่างสมบูรณ์ แต่คุณอาจต้องการปรับแต่งตัวเลือก 'termencoding'
Christian Brabandt

@ChristianBrabandt เว้นเสียแต่ว่าฉันกำลังทำสิ่งที่ผิดนั่นดูเหมือนจะไม่ช่วยอะไร ฉันลองตั้งค่า tenc เป็น latin1, utf8 และ cp850 ดูเหมือนว่าไม่มีใครทำเคล็ดลับ
Roflo

คำตอบ:


2

คำตอบสั้น ๆ

dot.exeปัญหาอยู่ใน GraphViz สามารถเปิดไฟล์ที่มีเส้นทาง Unicode ใน Linux แต่ไม่ใช่ Windows ยกเว้นว่า (อาจจะ) หากคอมไพล์ด้วย Visual Studio 2005

วิจัย

หน้ารหัสถูกตั้งค่า850, UTF-8กลุ่มการเข้ารหัสเพื่อ

ป้อนคำอธิบายรูปภาพที่นี่

มันไม่ได้ให้ข้อผิดพลาดเหมือนกัน แต่dot.exeดูเหมือนว่าจะได้รับข้อโต้แย้งที่ผิด ฉันพยายามส่งชื่อไฟล์เดียวกันไปยังโปรแกรมอื่น

ป้อนคำอธิบายรูปภาพที่นี่

และมันใช้งานได้ดี การดำเนินการทั้งสองอย่างdot.exeและtypeโดยตรงcmd.exeจะให้ผลลัพธ์เดียวกันดังนั้น Windows Console และ Vim จึงไม่เป็นปัญหา สิ่งต่อไปที่อาจทำให้เกิดข้อผิดพลาดนั้นdot.exeเอง ความสงสัยของฉันคือว่ามันไม่ทราบวิธีจัดการกับข้อโต้แย้งที่เข้ารหัสแบบ Unicode อย่างถูกต้องเนื่องจากไม่ใช่คำสั่งคอนโซลทั้งหมดที่ทำได้:

https://ss64.com/nt/chcp.html

หากคุณต้องการการสนับสนุน Unicode แบบสมบูรณ์ให้ใช้ PowerShell ยังคงมีการสนับสนุนที่ จำกัด มากสำหรับ Unicode ในเชลล์ CMD, ไพพ์, การเปลี่ยนเส้นทางและคำสั่งส่วนใหญ่ยังคงเป็น ANSI เท่านั้น คำสั่งเดียวที่ใช้งานได้คือ DIR, FOR / F และ TYPE ทำให้สามารถอ่านและเขียนไฟล์และชื่อไฟล์ (UTF-16LE / BOM) แต่ไม่มาก

ฉันค้นหาบนเว็บหากมีการรองรับ Unicode ใน GraphViz และพบว่ามันรองรับไฟล์ Unicode แต่ไม่มีอะไรเกี่ยวกับการสนับสนุน Unicode สำหรับชื่อไฟล์ ฉันไม่พบรายงานใด ๆ ในเครื่องมือติดตามบั๊กของ GraphViz หรือโพสต์บนฟอรัมเกี่ยวกับคนอื่นที่สนใจอ่านไฟล์ Unicode ชื่อ ดังนั้นฉันจึงค้นหามันในแหล่งที่มา นี่คือสิ่งที่เป็นdot.exeจุดเริ่มต้นที่มีลักษณะดังนี้:

graphviz-2.40.1\cmd\dot\dot.c

int main(int argc, char **argv)
{
    . . .

/* --------------------> ARGS ARE BEING PASSED HERE */
    gvParseArgs(Gvc, argc, argv);

    . . .

ตามargvหลุมกระต่ายลง:graphviz-2.40.1\lib\common\args.c

int gvParseArgs(GVC_t *gvc, int argc, char** argv)
{
    int rv;
    if ((argc = neato_extra_args(gvc, argc, argv)) < 0)    return (1-argc);
    if ((argc = fdp_extra_args(gvc, argc, argv)) < 0)      return (1-argc);
    if ((argc = memtest_extra_args(gvc, argc, argv)) < 0)  return (1-argc);
    if ((argc = config_extra_args(gvc, argc, argv)) < 0)   return (1-argc);

/* -------------------->  HERE GO ALL NON-FLAG ARTUMENTS */
    if ((rv = dotneato_args_initialize(gvc, argc, argv)))  return rv;

    if (Verbose) gvplugin_write_status(gvc);
    return 0;
}

graphviz-2.40.1\lib\common\input.c

int dotneato_args_initialize(GVC_t * gvc, int argc, char **argv)
{
    for (i = 1; i < argc; i++) {
        if (argv[i] && argv[i][0] == '-') {

            . . .

/* -------------------->  JUST CASUALLY COPYING CHAR POINTERS */
        } else if (argv[i])
            gvc->input_filenames[nfiles++] = argv[i];
    }

และสุดท้าย graphviz-2.40.1\lib\common\input.c

graph_t *gvNextInputGraph(GVC_t *gvc)
{
    . . . .

/* -------------------->  OPENING THE FILES FOR READ WITH FOPEN */
    while ((fn = gvc->input_filenames[fidx++]) && !(fp = fopen(fn, "r")))  {

        . . .

    }

ตามที่ MDSN ระบุไว้:

fopenฟังก์ชั่นเปิดแฟ้มที่ระบุโดยชื่อไฟล์ _wfopenเป็นรุ่นที่กว้างตัวอักษรของfopen ; อาร์กิวเมนต์ของ_wfopenเป็นสตริงตัวกว้าง _wfopenและfopenทำตัวเหมือนกัน เพียงแค่ใช้_wfopenไม่มีผลกับชุดอักขระที่ใช้รหัสในไฟล์สตรีม

ใน c ++ Visual 2005 fopen รองรับกระแสไฟล์ Unicode

น่าเสียดายตัวเลือกเดียวที่มีคือการเปลี่ยนชื่อไฟล์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.