รับข้อผิดพลาด“ การเปลี่ยนเส้นทางที่คลุมเครือ”


173

บรรทัดต่อไปนี้ในสคริปต์ Bash ของฉัน

 echo $AAAA"     "$DDDD"         "$MOL_TAG  >>  ${OUPUT_RESULTS}

ให้ข้อผิดพลาดนี้กับฉัน:

 line 46: ${OUPUT_RESULTS}: ambiguous redirect

ทำไม?


10
คุณไม่ได้แสดงทั้งหมด คุณได้รับ${OUPUT_RESULTS}ที่ไหน นอกจากนี้ยังเป็นข้อผิดพลาดการสะกดหากคุณหมายถึง$OUTPUT_RESULTS}
ghostdog74

หากมีคนเขียนOUPUT_RESULTS = "filename.log"คนหนึ่งจะได้รับการเปลี่ยนเส้นทางที่ไม่ชัดเจน เพราะทุบตีต้องการพื้นที่ไม่มีรอบ=ผู้ประกอบการ
Poutrathor

คำตอบ:


269

ทุบตีอาจป้านสวยบางครั้ง

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

$ echo hello >
bash: syntax error near unexpected token `newline`

$ echo hello > ${NONEXISTENT}
bash: ${NONEXISTENT}: ambiguous redirect

$ echo hello > "${NONEXISTENT}"
bash: : No such file or directory

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


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

@PaulJackson ... นั่นไม่จริง ในฐานะผู้สาธิตการคัดลอกและวาง: sh -c 'echo hello >/tmp/hello' >/tmp/worldทำงานได้อย่างถูกต้อง
ชาร์ลส์ดัฟฟี่

24

คุณมีชื่อตัวแปรOUPUT_RESULTSหรือว่ามีโอกาสมากขึ้นOUTPUT_RESULTS?


michael@isolde:~/junk$ ABC=junk.txt
michael@isolde:~/junk$ echo "Booger" > $ABC
michael@isolde:~/junk$ echo "Booger" >> $ABB
bash: $ABB: ambiguous redirect
michael@isolde:~/junk$ 

2
หากคุณABC="junk file.txt"สิ่งนี้จะยังคงมีปัญหาอยู่
Charles Duffy

15

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

echo $AAAA"     "$DDDD"         "$MOL_TAG  >>  "${OUPUT_RESULTS}"

เช่นการเปลี่ยนเส้นทางที่ไม่ชัดเจน

$ var="file with spaces"
$ echo $AAAA"     "$DDDD"         "$MOL_TAG >> ${var}
bash: ${var}: ambiguous redirect
$ echo $AAAA"     "$DDDD"         "$MOL_TAG >> "${var}"
$ cat file\ with\ spaces
aaaa     dddd         mol_tag

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

@JUSTMYcorrectOPINION เชลล์ไม่แยกวิเคราะห์อีกครั้งหลังจากการขยายพารามิเตอร์ - หมายความว่าเนื้อหาหลังจากช่องว่างภายในผลลัพธ์การขยายตัวไม่สามารถส่งผลให้มีการเติมไวยากรณ์ในส่วนอื่นได้
Charles Duffy

5

ฉันเพิ่งพบว่าช่องว่างในชื่อของไฟล์เปลี่ยนเส้นทางจะทำให้ข้อความ "เปลี่ยนเส้นทางคลุมเครือ"

ตัวอย่างเช่นหากคุณเปลี่ยนเส้นทางไปapplication$(date +%Y%m%d%k%M%S).logและคุณระบุอักขระการจัดรูปแบบที่ไม่ถูกต้องการเปลี่ยนเส้นทางจะล้มเหลวก่อนเวลา 10.00 น. ถ้าคุณใช้application$(date +%Y%m%d%H%M%S).logมันจะประสบความสำเร็จ นี่เป็นเพราะ%kรูปแบบให้ผลตอบแทน' 9'9AM โดยที่%Hอัตราผลตอบแทน'09'9AM

echo $(date +%Y%m%d%k%M%S) จะช่วยให้ 20140626 95138

echo $(date +%Y%m%d%H%M%S) จะช่วยให้ 20140626095138

วันที่ผิดพลาดอาจให้อะไรเช่น:

echo "a" > myapp20140626 95138.log

โดยที่ต่อไปนี้คือสิ่งที่ต้องการ:

echo "a" > myapp20140626095138.log

ข้อผิดพลาดคือคุณควรมีเครื่องหมายคำพูดล้อมรอบตัวแปรไม่ว่าจะมีช่องว่างหรือไม่ ดูเวลาที่จะตัดเครื่องหมายคำพูดรอบ ๆ ตัวแปรเชลล์?
tripleee

5

เส้นทางที่ระบุใน $ {OUPUT_RESULTS} มีอักขระช่องว่างหรือไม่ ถ้าเป็นเช่นนั้นคุณอาจต้องการพิจารณาการใช้... >> "${OUPUT_RESULTS}"(ใช้เครื่องหมายคำพูด)

(คุณอาจต้องการพิจารณาเปลี่ยนชื่อตัวแปรเป็น${OUTPUT_RESULTS})


1

ฉันเพิ่งพบข้อผิดพลาดนี้ในสคริปต์ทุบตี ปัญหานี้เกิดขึ้นโดยบังเอิญ \ ในตอนท้ายของบรรทัดก่อนหน้าซึ่งให้ข้อผิดพลาด


1

อีกสิ่งหนึ่งที่อาจทำให้ "การเปลี่ยนเส้นทางคลุมเครือ" อยู่\t \n \rในชื่อตัวแปรที่คุณกำลังเขียนด้วย

อาจจะไม่\n\r? แต่ผิดที่ด้านความระมัดระวัง

ลองสิ่งนี้

echo "a" > ${output_name//[$'\t\n\r']}

ฉันได้รับผลกระทบนี้ขณะที่แยกวิเคราะห์ HTML แท็บ\tที่จุดเริ่มต้นของบรรทัด


ข้อผิดพลาดไม่ได้อ้างอิงตัวแปร ดูเวลาที่จะตัดเครื่องหมายคำพูดรอบ ๆ ตัวแปรเชลล์?
tripleee

1

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

  1. vim a.sh เพื่อสร้างสคริปต์
  2. แก้ไขสคริปต์ที่จะมี (logit="/home/ubuntu/test.log" && echo "a") >> ${logit}
  3. chmod +x a.sh เพื่อให้สามารถเรียกใช้งานได้
  4. a.sh

หากคุณทำเช่นนี้คุณจะได้รับ "/home/ubuntu/a.sh: บรรทัดที่ 1: $ logit: การเปลี่ยนเส้นทางที่ไม่ชัดเจน" นี้เป็นเพราะ

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

จากการใช้วงเล็บเพื่อจัดกลุ่มและขยายการแสดงออก

หากต้องการแก้ไขสิ่งนี้คุณสามารถแก้ไขสคริปต์ในขั้นตอนที่ 2 เพื่อกำหนดตัวแปรภายนอกวงเล็บ: logit="/home/ubuntu/test.log" && (echo "a") >> $logit


0

หากคุณกำลังใช้ชื่อตัวแปรในคำสั่งเชลล์คุณจะต้องเชื่อมโยงมันด้วย+เครื่องหมาย

ตัวอย่างเช่น :

หากคุณมีไฟล์สองไฟล์และคุณจะไม่ใช้รหัสอย่างหนักในชื่อไฟล์คุณต้องการใช้ชื่อตัวแปรแทน
"input.txt" = x
"output.txt" = y

จากนั้น ('คำสั่งเชลล์ภายในเครื่องหมายคำพูด' + x> + y)

มันจะทำงานด้วยวิธีนี้โดยเฉพาะถ้าคุณใช้สิ่งนี้ในโปรแกรมไพ ธ อนด้วยคำสั่ง os.system


0

นี่อาจเป็นกรณีเช่นกัน

คุณยังไม่ได้ระบุไฟล์ในตัวแปรและเปลี่ยนเส้นทางไปที่มันจากนั้น bash จะโยนข้อผิดพลาดนี้

files=`ls`
out_file = /path/to/output_file.t
for i in `echo "$files"`;
do
    content=`cat $i` 
    echo "${content}  ${i}" >> ${out_file}
done

ตัวแปรout_fileไม่ได้รับการตั้งค่าอย่างถูกต้องดังนั้นอย่าลืมตรวจสอบสิ่งนี้ BTW รหัสนี้กำลังพิมพ์เนื้อหาทั้งหมดและชื่อไฟล์บนคอนโซล


0

ฉันพบข้อผิดพลาดนี้เมื่อพยายามใช้การขยายรั้งเพื่อเขียนเอาต์พุตไปยังหลายไฟล์

ตัวอย่างเช่น: echo "text" > {f1,f2}.txtผลลัพธ์-bash: {f1,f2}.txt: ambiguous redirect

ในกรณีนี้ใช้teeเพื่อส่งออกไปยังหลายไฟล์:

echo "text" | tee {f1,f2,...,fn}.txt 1>/dev/null

1>/dev/nullจะป้องกันไม่ให้ข้อความจากการถูกเขียนไปstdout

หากคุณต้องการใช้ไฟล์ต่อท้าย tee -a

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