เชลล์สคริปต์: ฉันจะเขียนเนื้อหาหลายบรรทัดไปยังไฟล์ได้อย่างไรหากไฟล์ไม่มีอยู่?


9

ฉันต้องการสร้างไฟล์/opt/nginx/conf.d/default.confด้วยเนื้อหานี้ผ่านเชลล์สคริปต์และสร้างไฟล์หากไม่มีอยู่:

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    root /usr/share/nginx/html;
}

ฉันจะเขียนเนื้อหาหลายบรรทัดผ่านเชลล์สคริปต์ได้อย่างไร

ฉันสร้างไดเรกทอรี

sudo mkdir -p /opt/nginx/conf.d

แต่ฉันไม่รู้วิธีเขียนไฟล์


1
คุณสามารถใช้> (เพื่อเขียนทับไฟล์) หรือ >> (เพื่อต่อท้ายหากมีอยู่แล้ว) ตัวอย่าง: echo "hello world"> file.txt
Rob

เป็นข้อความแบบคงที่ทั้งหมดหรือส่วนใดส่วนหนึ่งของมันจะถูกแทนที่ด้วยค่าแบบไดนามิก? (เช่นชื่อโฮสต์พอร์ตไดเรกทอรีราก ฯลฯ )
Jeff Schaller

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

คำตอบ:


13

สรุป: ใช้>>เพื่อผนวกใช้[ -f file ]เพื่อทดสอบ

ลอง

if [ ! -f myfile ]
then
   cat <<EOF > myfile
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name $server ;
    root /usr/share/nginx/html;
}
EOF
fi
  • ไวยากรณ์cat <<EOFถูกเรียกว่า " here document "
  • $server จะถูกแทนที่ด้วยค่าของมันหรือว่างเปล่าหากไม่ได้กำหนด
  • ตามที่ระบุไว้คุณสามารถใช้เครื่องหมายคำพูดเดี่ยว'EOF'เพื่อหลีกเลี่ยงการแทนที่ var ถ้ามี
  • คุณสามารถมีเสียงสะท้อนได้หลายเสียง (ซึ่งอาจเป็นเรื่องลำบากที่จะรักษาหากเสียงสะท้อนมากเกินไป)

    echo "## foo.conf" > foo.conf
    echo param1=hello >> foo.conf
    echo param2=world >> foo.conf
    

prepending

ไม่มี prepend โดยตรงใน bash ใช้ไฟล์ชั่วคราว

mv file file_tmp
cat new_content file_tmp > file
rm file_tmp

หรือแก้ไข

sed -i -e '1r new_file' -e 'wq' file

ฉันจะเพิ่มเนื้อหาหลายบรรทัดลงในไฟล์ได้อย่างไร
user3142695

1
การเปลี่ยนแปลงที่น่าสนใจอีกอย่างที่ต้องทำคือการอ้างถึงสตริงข้อ จำกัด here-doc ดังนั้นคำที่มี$(ถ้ามี) จะไม่ถูกใช้เป็นตัวแปรดังนั้นจึงไม่ได้รับการขยาย
Inian

@ user3142695 วิธีที่ง่ายที่สุดในการเขียนเอกสารนี่คือไฟล์แยกต่างหากจากนั้นcatทั้งสองไฟล์เข้าด้วยกันและเปลี่ยนชื่อผลลัพธ์
Kusalananda

หากต้องการแยกหลาย ๆechos ก็ยังมีประสิทธิภาพมากกว่าที่จะมีการเปลี่ยนเส้นทางเพียงครั้งเดียวโดยวางไว้ในบล็อก: { echo "foo"; echo "bar"; echo "baz"; } >file- วิธีที่เราไม่ได้เปิดอีกครั้งfileทุกครั้งที่เราต้องการที่จะเขียนบรรทัดเดียวกับมัน และปิดเมื่อบรรทัดนั้นเสร็จสิ้น
Charles Duffy

เอกสารอื่นที่ใช้ประโยชน์ได้ที่นี่:cat << EOF | sudo tee /opt/nginx/conf.d/default.conf ...
lp1051

3

หากไฟล์ /opt/nginx/conf.d/default.conf ไม่ได้อยู่แล้วพิมพ์ (ฉ) สตริงคงลงในแฟ้มนี้:

[ -f /opt/nginx/conf.d/default.conf ] || printf 'server {\n    listen 80 default_server;\n    listen [::]:80 default_server;\n    server_name _;\n    root /usr/share/nginx/html;\n}\n' > /opt/nginx/conf.d/default.conf

1
ฉันคิดว่าprintf '%s\n' "first line" "second line"อาจจะอ่านง่ายขึ้นอีกนิด ว่าวิธีหนึ่งที่ไม่จำเป็นต้องอ่านผ่านสตริงทั้งจะคิดออกว่าจะหนี ..
ชาร์ลส์ดัฟฟี่
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.