ฉันต้องการเรียกใช้สคริปต์เพื่อเปลี่ยนไดเรกทอรีการทำงานปัจจุบัน:
#!/bin/bash
cd web/www/project
แต่หลังจากที่ฉันเรียกใช้แล้ว pwd ปัจจุบันยังคงไม่เปลี่ยนแปลง! ฉันจะทำสิ่งนั้นได้อย่างไร
ฉันต้องการเรียกใช้สคริปต์เพื่อเปลี่ยนไดเรกทอรีการทำงานปัจจุบัน:
#!/bin/bash
cd web/www/project
แต่หลังจากที่ฉันเรียกใช้แล้ว pwd ปัจจุบันยังคงไม่เปลี่ยนแปลง! ฉันจะทำสิ่งนั้นได้อย่างไร
คำตอบ:
มันเป็นพฤติกรรมที่คาดหวังและพูดคุยกันหลายครั้งแล้ว
สคริปต์รันในเชลล์ย่อยและไม่สามารถเปลี่ยนไดเร็กทอรีการทำงานเชลล์พาเรนต์ ผลของมันจะหายไปเมื่อมันเสร็จสิ้น
หากต้องการเปลี่ยนไดเรกทอรีอย่างถาวรคุณควรระบุที่มาของสคริปต์ดังเช่น
. ./script
source ./script
เหมือนกันหรือไม่
.
และsource
เท่าเทียมกันในการทุบตี 2. เราไม่จำเป็นต้องใช้./
ก่อนชื่อไฟล์ถ้ามันอยู่ในไดเรกทอรีเดียวกัน มันก็โอเคที่จะเรียกใช้สิ่งนี้เท่านั้น:. script
สำหรับงานเล็ก ๆ เช่นนี้แทนที่จะสร้างสคริปต์ให้สร้างนามแฝงเช่นนี้
$ alias cdproj='cd /dir/web/www/proj'
คุณควรเพิ่มสิ่งนี้ลงใน.bashrc
ไฟล์ของคุณหากคุณต้องการให้มันตั้งค่าสำหรับทุกเชลล์แบบโต้ตอบ
$ cdproj
ตอนนี้คุณสามารถทำงานนี้เป็น
eval `./script`
หรือeval $(./script)
ดำเนินการคำสั่งเหล่านั้น นี่เป็นวิธีการทั่วไปสำหรับคำสั่งที่จำเป็นต้องอัพเดตสภาพแวดล้อมของเชลล์ที่กล่าวอ้าง
eval
แนวทาง
exec bash
ในตอนท้ายสคริปต์ทุบตีทำงานในสภาพแวดล้อมปัจจุบันหรือกับลูก ๆ ของมัน แต่ไม่เคยอยู่ในสภาพแวดล้อมหลัก
อย่างไรก็ตามคำถามนี้มักจะถูกถามเพราะต้องการทิ้งไว้ที่พรอมต์ bash ในไดเรกทอรีหนึ่งหลังจากเรียกใช้งานสคริปต์ทุบตีจากไดเรกทอรีอื่น
หากเป็นกรณีนี้ให้เรียกใช้อินสแตนซ์ bash ของเด็กที่ส่วนท้ายของสคริปต์:
#!/usr/bin/env bash
cd desired/directory
exec bash
สิ่งนี้จะสร้าง subshell ใหม่ พิมพ์exit
เพื่อกลับไปที่เชลล์แรกที่สคริปต์เริ่มทำงานในตอนแรก
exec
ถือว่าเป็นมักจะเป็นที่พึ่งสุดท้ายของตัวโกง .. มี :)
exit
(หรือ Ctrl + D) คุณจะต้องทำเช่นนั้น 11 ถึง 21 ครั้ง (2) ข้อเสียเปรียบอีกประการของการใช้สคริปต์ที่เรียกใช้งานได้คือถ้าคุณตั้งค่าตัวเลือกเชลล์ใด ๆ (เช่น dotglob
หรือ globstar
) ในเซสชันเชลล์เชิงโต้ตอบของคุณคุณจะสูญเสียมันเนื่องจากคุณกำลังเริ่มเชลล์ใหม่
ในขณะที่มีคำตอบที่ดำเนินการอย่างถูกต้องตามที่คุณต้องการวิธีการมาตรฐานที่มากขึ้นสำหรับวัตถุประสงค์ดังกล่าวคือการสร้างลิงก์สัญลักษณ์:
ln -s ~/web/www/project proj #use full path to dir!
จากนั้นคุณสามารถcd
ไปที่ไดเรกทอรีโดยใช้ชื่อproj
:
cd proj
วิธีนี้มีความยืดหยุ่นมากขึ้นเพราะคุณสามารถเข้าถึงไฟล์โดยใช้ชื่อย่อโดยไม่ต้องcd
:
ls proj/ #note the endslash!
vim proj/file.x
ขึ้นอยู่กับสิ่งที่คุณกำลังทำวิธีแก้ปัญหาอื่นสามารถสร้างฟังก์ชั่นแทนสคริปต์
ตัวอย่าง:
สร้างฟังก์ชั่นในไฟล์สมมติว่า/home/aidin/my-cd-script
:
function my-cd() {
cd /to/my/path
}
จากนั้นรวมไว้ในbashrc
หรือzshrc
ไฟล์ของคุณ:
# Somewhere in rc file
source /home/aidin/my-cd-script
ตอนนี้คุณสามารถใช้มันเหมือนคำสั่ง:
$ my-cd
ทำไมไม่ใช้ "exec" มันตะเข็บเพื่อทำสิ่งที่ฉันต้องการ
#!/bin/bash
cd someplace
exec bash
~/someplace
exit
(หรือ Ctrl + D) คุณจะต้องทำเช่นนั้น 11 ถึง 21 ครั้ง
dotglob
หรือ globstar
) คุณจะสูญเสียมันไปเพราะคุณกำลังเริ่มเชลล์ใหม่ … (ต่อ)
คุณสามารถทำได้โดยใช้ฟังก์ชั่นหรือการใช้ && ตัวอย่างร้องติดตั้ง Zabbix และสร้างไฟล์ที่มีบรรทัดอยู่ข้างใน
Ex:
#!/bin/bash
# Create Function:
installZabbix(){
cd /usr/src/zabbix-4.2.4;
./configure --enable-agent;
make install;
cd /usr/src/;
>file;
echo "Hi, this is a file." >>file;
}
# Call the function:
installZabbix
หรือ:
#!/bin/bash
cd /usr/src/zabbix-4.2.4 && ./configure --enable-agent && make install && cd /usr/src && >file && echo "Hi, this is a file." >>file
return
เพื่อหลบหนีจากสคริปต์ที่มาในลักษณะนี้ไม่ใช่exit
- พวกเขาเป็นเหมือนฟังก์ชั่นของเชลล์และexit
จะออกจากเชลล์ที่มาจากสคริปต์