ฉันจะเขียนเอกสารที่นี่ไปยังไฟล์ใน Bash script ได้อย่างไร?
ฉันจะเขียนเอกสารที่นี่ไปยังไฟล์ใน Bash script ได้อย่างไร?
คำตอบ:
อ่านขั้นสูงทุบตี Scripting คู่มือบทที่ 19 ที่นี่เอกสาร
นี่คือตัวอย่างที่จะเขียนเนื้อหาไปยังไฟล์ที่ /tmp/yourfilehere
cat << EOF > /tmp/yourfilehere
These contents will be written to the file.
        This line is indented.
EOFโปรดทราบว่า 'EOF' สุดท้าย (The LimitString) ไม่ควรมีช่องว่างด้านหน้าคำเพราะหมายความว่าLimitStringจะไม่ได้รับการยอมรับ
ในเชลล์สคริปต์คุณอาจต้องการใช้การเยื้องเพื่อให้โค้ดอ่านได้อย่างไรก็ตามสิ่งนี้อาจมีผลที่ไม่พึงประสงค์จากการเยื้องข้อความภายในเอกสารที่นี่ของคุณ ในกรณีนี้ใช้<<-(ตามด้วยเส้นประ) เพื่อปิดการใช้งานแท็บนำ ( โปรดทราบว่าเพื่อทดสอบสิ่งนี้คุณจะต้องแทนที่ช่องว่างนำหน้าด้วยอักขระแท็บเนื่องจากฉันไม่สามารถพิมพ์อักขระแท็บจริงได้ที่นี่)
#!/usr/bin/env bash
if true ; then
    cat <<- EOF > /tmp/yourfilehere
    The leading tab is ignored.
    EOF
fiหากคุณไม่ต้องการตีความตัวแปรในข้อความให้ใช้เครื่องหมายคำพูดเดี่ยว:
cat << 'EOF' > /tmp/yourfilehere
The variable $FOO will not be interpreted.
EOFในการไพพ์ heredoc ผ่านไพพ์ไลน์คำสั่ง:
cat <<'EOF' |  sed 's/a/b/'
foo
bar
baz
EOFเอาท์พุท:
foo
bbr
bbz... หรือเพื่อเขียน heredoc ไปยังไฟล์โดยใช้sudo:
cat <<'EOF' |  sed 's/a/b/' | sudo tee /etc/config_file.conf
foo
bar
baz
EOF<<<สิ่งที่พวกเขาเรียกว่า?
                    <<<ถูกเรียกว่า 'Here Strings' รหัสเหมือนจะส่งผลให้ในสตริงtr a-z A-Z <<< 'one two three' ONE TWO THREEข้อมูลเพิ่มเติมที่en.wikipedia.org/wiki/Here_document#Here_strings
                    <<'EOF' <<EOF
                    แทนที่จะใช้catและการเปลี่ยนเส้นทาง I / O อาจมีประโยชน์ในการใช้teeแทน:
tee newfile <<EOF
line 1
line 2
line 3
EOFมันกระชับกว่าและแตกต่างจากผู้ให้บริการเปลี่ยนเส้นทางซึ่งสามารถใช้ร่วมกับsudoหากคุณต้องการเขียนไปยังไฟล์ที่มีสิทธิ์รูท
> /dev/nullที่ท้ายบรรทัดแรกเพื่อป้องกันเนื้อหาของไฟล์ here ที่จะถูกแสดงเป็น stdout เมื่อไฟล์ถูกสร้างขึ้น
                    sudoมากกว่าเพราะความกะทัดรัด :-)
                    man teeตรวจสอบ ใช้การ-aตั้งค่าสถานะเพื่อผนวกแทนการเขียนทับ
                    บันทึก:
คำถาม (วิธีเขียนเอกสารที่นี่ (aka heredoc ) ไปยังไฟล์ในสคริปต์ทุบตี) มี (อย่างน้อย) 3 มิติหลักหรือคำถามย่อยอิสระ:
root) เป็นเจ้าของไฟล์หรือไม่(มีส่วนข้อมูลย่อย / คำถามย่อยอื่น ๆ ที่ฉันไม่ถือว่าสำคัญพิจารณาแก้ไขคำตอบนี้เพื่อเพิ่ม!) ต่อไปนี้เป็นชุดค่าผสมที่สำคัญยิ่งขึ้นของมิติของคำถามข้างต้นพร้อมตัวระบุที่แตกต่างหลากหลาย - ไม่มีอะไรเลย ศักดิ์สิทธิ์EOFเพียงตรวจสอบให้แน่ใจว่าสตริงที่คุณใช้เป็นตัวระบุการคั่นของคุณจะไม่เกิดขึ้นภายใน heredoc ของคุณ:
ในการเขียนทับไฟล์ที่มีอยู่ (หรือเขียนไปยังไฟล์ใหม่) ที่คุณเป็นเจ้าของให้แทนที่การอ้างอิงตัวแปรภายใน heredoc:
cat << EOF > /path/to/your/file
This line will write to the file.
${THIS} will also write to the file, with the variable contents substituted.
EOFในการต่อท้ายไฟล์ที่มีอยู่ (หรือเขียนลงในไฟล์ใหม่) ที่คุณเป็นเจ้าของให้แทนที่การอ้างอิงตัวแปรภายใน heredoc:
cat << FOE >> /path/to/your/file
This line will write to the file.
${THIS} will also write to the file, with the variable contents substituted.
FOEหากต้องการเขียนทับไฟล์ที่มีอยู่ (หรือเขียนไปยังไฟล์ใหม่) ที่คุณเป็นเจ้าของด้วยเนื้อหาที่แท้จริงของ heredoc:
cat << 'END_OF_FILE' > /path/to/your/file
This line will write to the file.
${THIS} will also write to the file, without the variable contents substituted.
END_OF_FILEในการต่อท้ายไฟล์ที่มีอยู่ (หรือเขียนลงในไฟล์ใหม่) ที่คุณเป็นเจ้าของด้วยเนื้อหาที่แท้จริงของ heredoc:
cat << 'eof' >> /path/to/your/file
This line will write to the file.
${THIS} will also write to the file, without the variable contents substituted.
eofในการเขียนทับไฟล์ที่มีอยู่ (หรือเขียนไปยังไฟล์ใหม่) ที่เป็นของ root ให้แทนที่การอ้างอิงตัวแปรภายใน heredoc:
cat << until_it_ends | sudo tee /path/to/your/file
This line will write to the file.
${THIS} will also write to the file, with the variable contents substituted.
until_it_endsในการต่อท้ายไฟล์ที่มีอยู่ (หรือเขียนลงในไฟล์ใหม่) user = foo ที่เป็นเจ้าของโดยมีเนื้อหาตามตัวอักษรของ heredoc:
cat << 'Screw_you_Foo' | sudo -u foo tee -a /path/to/your/file
This line will write to the file.
${THIS} will also write to the file, without the variable contents substituted.
Screw_you_Foo-a== --append; เช่น->tee -a teeดูinfo tee(ฉันจะพูดที่นี่ แต่ความเห็นมาร์กอัป จำกัด มากเกินไป
                    sudo tee /path/to/your/file << 'Screw_you_Foo'หรือไม่?
                    FOEแทนที่จะเป็นEOFในตัวอย่างผนวก?
                    เพื่อสร้างคำตอบของ @ Livven ต่อไปนี้เป็นชุดค่าผสมที่มีประโยชน์
การทดแทนตัวแปร, แท็บนำยังคงอยู่, เขียนทับไฟล์, echo to stdout
tee /path/to/file <<EOF
${variable}
EOFไม่มีการทดแทนตัวแปร , แท็บนำยังคงอยู่, เขียนทับไฟล์, echo to stdout
tee /path/to/file <<'EOF'
${variable}
EOFการแทนที่ตัวแปร, แท็บนำออก , เขียนทับไฟล์, echo to stdout
tee /path/to/file <<-EOF
    ${variable}
EOFการทดแทนตัวแปร, แท็บนำยังคงอยู่, ต่อท้ายไฟล์ , echo to stdout
tee -a /path/to/file <<EOF
${variable}
EOFการทดแทนตัวแปร, แท็บนำยังคงอยู่, เขียนทับไฟล์, ไม่มี echo to stdout
tee /path/to/file <<EOF >/dev/null
${variable}
EOFด้านบนสามารถใช้ร่วมกับได้sudoเช่นกัน
sudo -u USER tee /path/to/file <<EOF
${variable}
EOFเมื่อจำเป็นต้องมีการอนุญาตรูทสำหรับไฟล์ปลายทางให้ใช้|sudo teeแทน>:
cat << 'EOF' |sudo tee /tmp/yourprotectedfilehere
The variable $FOO will *not* be interpreted.
EOFสำหรับคนในอนาคตที่อาจมีปัญหานี้รูปแบบต่อไปนี้ใช้งานได้:
(cat <<- _EOF_
        LogFile /var/log/clamd.log
        LogTime yes
        DatabaseDirectory /var/lib/clamav
        LocalSocket /tmp/clamd.socket
        TCPAddr 127.0.0.1
        SelfCheck 1020
        ScanPDF yes
        _EOF_
) > /etc/clamd.confcat << END > afileตามด้วย heredoc ทำงานได้ดีอย่างสมบูรณ์
                    catดังที่แสดงในคำตอบที่ยอมรับ
                    catทำงานทั้งหมดภายใน subshell และผลลัพธ์ทั้งหมดของ subshell จะถูกเปลี่ยนเส้นทางไปยังไฟล์
                    ตัวอย่างเช่นคุณสามารถใช้มันได้:
ก่อน (ทำการเชื่อมต่อ ssh):
while read pass port user ip files directs; do
    sshpass -p$pass scp -o 'StrictHostKeyChecking no' -P $port $files $user@$ip:$directs
done <<____HERE
    PASS    PORT    USER    IP    FILES    DIRECTS
      .      .       .       .      .         .
      .      .       .       .      .         .
      .      .       .       .      .         .
    PASS    PORT    USER    IP    FILES    DIRECTS
____HEREที่สอง (รันคำสั่ง):
while read pass port user ip; do
    sshpass -p$pass ssh -p $port $user@$ip <<ENDSSH1
    COMMAND 1
    .
    .
    .
    COMMAND n
ENDSSH1
done <<____HERE
    PASS    PORT    USER    IP
      .      .       .       .
      .      .       .       .
      .      .       .       .
    PASS    PORT    USER    IP    
____HEREที่สาม (รันคำสั่ง):
Script=$'
#Your commands
'
while read pass port user ip; do
    sshpass -p$pass ssh -o 'StrictHostKeyChecking no' -p $port $user@$ip "$Script"
done <<___HERE
PASS    PORT    USER    IP
  .      .       .       .
  .      .       .       .
  .      .       .       .
PASS    PORT    USER    IP  
___HEREมา (ใช้ตัวแปร):
while read pass port user ip fileoutput; do
    sshpass -p$pass ssh -o 'StrictHostKeyChecking no' -p $port $user@$ip fileinput=$fileinput 'bash -s'<<ENDSSH1
    #Your command > $fileinput
    #Your command > $fileinput
ENDSSH1
done <<____HERE
    PASS    PORT    USER    IP      FILE-OUTPUT
      .      .       .       .          .
      .      .       .       .          .
      .      .       .       .          .
    PASS    PORT    USER    IP      FILE-OUTPUT
____HEREฉันชอบวิธีนี้เพื่อความกระชับอ่านง่ายและนำเสนอในสคริปต์ที่เยื้อง:
<<-End_of_file >file
→       foo bar
End_of_fileในกรณีที่→       เป็นtabตัวอักษร