เหตุใดฉันจึงได้รับ“ บรรทัด 1: $ ': \ r': ไม่พบคำสั่ง "


13

ฉันใช้ Cygwin บนแล็ปท็อปของฉัน (DOS) ฉันมีชุดของสคริปต์จากเพื่อนร่วมงานของฉันและของฉันเอง ฉันไม่ใช่คนไอทีไม่เก่งเรื่องยูนิกซ์ ฉันทำตามไวยากรณ์ของเพื่อนร่วมงานและสามารถจัดการสิ่งต่าง ๆ ได้ง่ายๆ

สคริปต์ทำงานได้ดีบนแล็ปท็อปเครื่องเก่าของฉัน ฉันเพิ่งเปลี่ยนแล็ปท็อปติดตั้ง Cygwin เมื่อฉันเรียกใช้สคริปต์สคริปต์จะไม่ทำงาน นี่เป็นตัวอย่างข้อผิดพลาดที่ฉันได้รับ:

line 1: $':\r': command not found
line 5: syntax error near unexpected token `$'\r''
line 5: `fi

นี่คือสคริปต์ 5 บรรทัดแรกของฉัน

:
iter=1
if [ -f iter.txt ]
   then rm ./iter.txt 
fi  

ใครช่วยกรุณาอธิบายว่าฉันจะแก้ไขปัญหานี้ได้อย่างไร?

คำตอบ:


29

คุณมีการสิ้นสุดบรรทัดแบบ Windows

คำสั่งไม่มี-op :แทนที่จะอ่านเป็น:<carriage return>แสดงเป็นหรือมากกว่าอย่างเต็มที่:\r$':\r'

วิ่งdos2unix scriptnameและคุณควรจะสบายดี


หากคุณไม่มีdos2unixสิ่งต่อไปนี้ควรทำงานได้เกือบทุกที่ (และฉันทดสอบบน MobaXterm บน Windows):

vi -b filename

จากนั้นviให้พิมพ์:

:%s/\r$//
:x

คุณดีไปแล้ว


ในvimซึ่งเป็นสิ่งที่คุณใช้ใน Cygwin viมีหลายวิธีในการทำเช่นนี้ อีกคนหนึ่งที่เกี่ยวข้องกับการfileformatตั้งค่าซึ่งสามารถใช้ค่าหรือdos unixเปลี่ยนอย่างชัดเจนหลังจากโหลดไฟล์ด้วย

set fileformat = unix
หรือบังคับรูปแบบไฟล์อย่างชัดเจนเมื่อเขียนไฟล์ด้วย

: w + fileformat = unix

สำหรับข้อมูลเพิ่มเติมให้ดูคำถามและคำตอบมากมายที่นี่ซึ่งครอบคลุมหัวข้อนี้รวมถึง:


เพียงต้องการชี้แจง "iter = 1" เป็นตัวนับของฉันที่จะใช้สำหรับจำนวนรอบของอัลกอริทึมทางคณิตศาสตร์ที่แบบจำลองของฉันจะต้องทำซ้ำในภายหลังเกิน 5 บรรทัดฉันเพิ่งโพสต์ 5 อันดับแรกไปกับ ข้อความผิดพลาด. ความคิดเห็นและคำแนะนำทั้งหมดได้รับการชื่นชมอย่างมาก !!
TPham

ฉันลองคำสั่งที่แนะนำ "$ tr -d ..... " แต่มีบางอย่างผิดปกติกับแล็ปท็อปของฉัน มันไม่ได้กลับไปที่ "$" แต่ ">" จะปรากฏบนหน้าจอแทน ฉันต้องใช้ contrl C เพื่อออกไป จากนั้นฉันทดสอบสคริปต์เพื่อดูว่าปัญหาได้รับการแก้ไขหรือไม่ แต่ยังคงมีอยู่ ขออภัยความรู้ของฉันในสาขานี้มีน้อยมาก! ฉันพยายามใช้สคริปต์ของฉันเพราะพวกเขาช่วยฉันได้มาก ขอบคุณทุกคนที่อดทนและเป็นประโยชน์กับฉัน
TPham

@TPham ดูการแก้ไข หากใช้งานได้ให้ใช้เครื่องหมายถูกถัดจากคำตอบเพื่อ "ยอมรับ" (ยอมรับว่าคำตอบใดแก้ปัญหาของคุณได้ดีที่สุด) unix.stackexchange.com/help/someone-answers
Wildcard

1
คำสั่งที่เป็นคำไม่ซับซ้อนกว่ามือใหม่มากไปกว่าคาถาลึกลับที่มีเครื่องหมายวรรคตอนเกือบทั้งหมด นี่ไม่จำเป็นต้องมีคำตอบแยกต่างหาก เพียงต้องการคำตอบนี้เพื่อพูดถึงว่าvimสามารถทำได้สองวิธีหนึ่งในนั้นใช้คำ หรือดีกว่ายังจะชี้ไปที่งานของผู้ใต้บังคับบัญชานี้ได้รับการตอบรับมากกว่าและมากกว่าที่นี่ในรายละเอียดมากเกินกว่าที่ใด ๆคำตอบในหน้านี้รวมทั้งunix.stackexchange.com/questions/88811เพียงสำหรับการเริ่ม
JdeBP

1
โปรดทราบว่าvi -b, \rส่วนขยายเป็นกลุ่มอยู่แล้ว ไม่ใช่ POSIX, ไม่ได้อยู่ใน nvi, elvis, Solaris vi ...
Stéphane Chazelas

10

นี่เป็นเพราะสคริปต์ได้รับการบันทึกโดยโปรแกรมแก้ไขที่ใช้การสิ้นสุดบรรทัด DOS (เช่น Notepad ++ เป็นต้น) คุณจะต้องลบสิ่งเหล่านี้ออกจากสคริปต์ของคุณ

หากต้องการทำสิ่งนี้ให้ใช้dos2unixไฟล์สคริปต์หรือ

$ tr -d '\r' <script >script.new && mv script.new script

(สิ่งนี้จะลบการรับคืนทั้งหมดจากที่ใดก็ได้ในสคริปต์)


สำหรับโค้ดในสคริปต์:

:
iter=1
if [ -f iter.txt ]
   then rm ./iter.txt 
fi  

สิ่งนี้อาจดูเหมือน

iter=1
if [ -f "./$iter.txt" ]; then
   rm "./$iter.txt"
fi

สิ่งนี้จะลบไฟล์1.txtออกจากไดเรกทอรีปัจจุบันหากมีอยู่ :คำสั่งไม่ทำอะไรเลย (เกือบ) และอาจถูกลบออก iterค่าของตัวแปรควรใช้เป็น$iterและจะยกมา แล้วฉันอาจจะชัดเจนกว่าความต้องการโดยใช้./เพื่อบอกว่าต้องพบไฟล์ในไดเรกทอรีปัจจุบัน

หากคุณกำลังวางแผนที่จะเปิดนี้เป็นห่วง (ที่นี่เป็นการลบไฟล์ทั้งหมด1.txt, 2.txt, ... 10.txt):

iter=1
while [ "$iter" -le 10 ]; then
    if [ -f "./$iter.txt" ]; then
        rm "./$iter.txt"
    fi
    iter=$(( iter + 1 ))
done

หรือถ้าเรารู้สึกส่อเสียด / ขี้เกียจ

rm -f {1..10}.txt

ในเชลล์ที่เข้าใจการขยายรั้ง


3
Notepad ++ จริง ๆ แล้วมีตัวเลือกในการใช้ตัวแบ่งบรรทัด Windows / Mac / Linux คุณเพียงแค่ต้องไปที่เมนูแก้ไขแล้วเลือก EOL Conversion-> Unix (LF) หรือคุณสามารถคลิกสองครั้งที่มุมด้านล่างขวาที่มีข้อความระบุไว้Windows (CR LF)และเปลี่ยนเป็นUnix (LF)
jesse_b

ขอบคุณทุกคนสำหรับคำแนะนำของคุณ ต้องการชี้แจง: "iter = 1" เป็นตัวนับที่ฉันใช้ในภายหลังเพื่อวัตถุประสงค์หลักของฉันนอกเหนือจากบรรทัดที่ 5
TPham

@TPham ยินดีต้อนรับ ฉันเพิ่งเบื่อและเอาโค้ดของคุณและปล่อยให้จิตใจของฉันทำงานแบบอิมเพรสชั่นนิสต์ด้วย
Kusalananda

rm -f [1-9].txt 10.txtหรือ แต่นั่นไม่ใช่ทั้งหมดเทียบเท่าเหตุผลเช่นถ้าไม่มีไฟล์ 1-9 แต่มีเป็นไฟล์ตัวอักษรที่เรียกว่า[1-9].txtแล้วมันจะถูกลบออก : D
Wildcard

5

สคริปต์ของคุณมีการวางสายผิด Windows ใช้ CR + LF (\ r \ n), Unix ใช้ LF (\ n) และ Classic MacOS ใช้ CR (\ r) dos2unixคุณจะต้องเปลี่ยนสายตอนจบกับแฟ้มได้รับผลกระทบทั้งหมดทั้งที่มีโปรแกรมแก้ไขข้อความหรือเครื่องมือแบบสแตนด์อโลนเช่น

FTP และระบบควบคุมเวอร์ชันเช่น SVN มักจะสามารถแปลงจุดสิ้นสุดบรรทัดได้อย่างเหมาะสมดังนั้นคุณอาจต้องการดูตัวเลือกเหล่านั้นสำหรับการถ่ายโอนไฟล์ในอนาคต

หากไฟล์เหล่านี้ไม่ได้ถูกถ่ายโอน แต่ใช้กับเครื่องเดียวคุณจะต้องค้นหาการตั้งค่าสำหรับการสิ้นสุดบรรทัดในโปรแกรมแก้ไขข้อความที่ต้องการ ส่วนใหญ่ที่โฆษณาว่า "สำหรับโปรแกรมเมอร์" จะมีตัวเลือกดังกล่าว


ขอบคุณทุกคนสำหรับคำแนะนำที่เป็นประโยชน์ ฉันเพิ่งลอง dos2unix แต่ดูเหมือนว่าฉันไม่มี จะค้นหาและลองอีกครั้ง
TPham

3

เป็นคำตอบเพิ่มเติมให้ฉันเพิ่มบันทึกย่อ / เคล็ดลับ ...

ก่อนอื่นสำหรับไฟล์ข้อความปกติคุณสามารถกำหนดได้อย่างง่ายดายว่าพวกเขามีบรรทัด Unix หรือ DOS ที่ลงท้ายด้วยfileคำสั่ง ตัวอย่างเช่น:

$ file test.txt
test.txt: ASCII text, with CRLF line terminators
$ dos2unix test.txt
dos2unix: converting file test.txt to Unix format...
$ file test.txt
test.txt: ASCII text

dos2unixหมายเหตุการใช้ของฉัน ฉันขอแนะนำให้คุณติดตั้ง ขึ้นอยู่กับวิธีที่คุณใช้ Cygwin คุณอาจพบว่าคุณต้องทำการแปลงนี้บ่อยครั้งเพียงพอที่จะให้ความสะดวกสบาย ที่สำคัญไม่มีโอกาสที่จะเกิดข้อผิดพลาดเหมือนกับที่คุณได้รับจากการแก้ไขด้วยตนเองที่กล่าวถึงที่นี่

ในการติดตั้งให้เริ่มต้นปฏิบัติการหลักของ Cygwin นั่นเป็นชื่อที่มีชื่อว่าเช่น setup-x86_64.exe หรือบางอย่างตามบรรทัดเหล่านั้น ตรวจสอบให้แน่ใจว่าคุณเห็นหน้าจอดังนี้:

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

เนื่องจากคุณทำการติดตั้งครั้งแรกเรียบร้อยแล้วคุณควรจะคลิกถัดไปจนกระทั่งคุณได้รับหน้าจอการเลือก เลือกเต็มในเมนูแบบเลื่อนลงและป้อน "dos2" ในช่องค้นหาและเลือกเครื่องมือตามที่แสดงที่นี่:

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

จากนั้นคลิกถัดไปอีกครั้งและให้การติดตั้งเสร็จสมบูรณ์ แค่นั้นแหละ. มีความสุข. Cygwin ยกเว้นความไม่สะดวกเป็นครั้งคราวนี้เป็นแพ็คเกจสุดยอดเยี่ยม


ขอบคุณมากสำหรับคำสั่ง B Layer ของคุณ! กลุ่ม Stack Exchange นี้มีประโยชน์มาก ฉันขอขอบคุณการสนับสนุนนี้
TPham

1

ถ้าไม่ใช่ dos2unix ก็มี 'พลิก'

$ flip -u yourfilename.txt

จะพลิกมันเพื่อใช้ปลายสายยูนิกซ์


1

ฉันใช้Notepad ++เพื่อแก้ไขสคริปต์ทุบตี (.sh) โดยเชื่อมต่อกับเซิร์ฟเวอร์โดยWinSCP
(ในการตั้งค่าตัวแก้ไข WinSCP เป็น Notepad ++: https://winscp.net/eng/docs/ui_editor_preferences )

นี่เป็นประโยชน์อย่างมากสำหรับการเปิดไฟล์จากเซิร์ฟเวอร์เพื่อแก้ไข / บันทึกแทน " Vim " editor
เมื่อคุณเปิดไฟล์ในNotepad ++ให้ดับเบิลคลิกที่คอลัมน์ที่ 7 ที่แถบสถานะที่ด้านล่างและเลือก " Unix (LF) "

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

นอกจากนี้คุณต้องเปลี่ยนรายการที่ 8 ด้วยการเข้ารหัส -> เข้ารหัสใน UTF-8 ในแถบด้านบน


0

คุณไม่จำเป็นต้องเปลี่ยนการเข้ารหัสบรรทัดของไฟล์จริงเพื่อให้ Bash ของ Cygwin ทำงานอย่างมีความสุขกับการเข้ารหัส end-of-line ของ Mac และ Windows มีตัวเลือกที่คุณต้องเปิด

เพียงอัปเดตของคุณ~/.bash_profileเพื่อให้มี

export SHELLOPTS
set -o igncr

ดูhttps://ptolemy.berkeley.edu/projects/chess/softdevel/faq/5.html

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