เหตุใดจึงไม่ใช้สองคำสั่ง cd ในสคริปต์ทุบตีรันคำสั่งที่สอง


15

ฉันได้เขียนสคริปต์ทุบตีซึ่งสร้างชุดของไดเรกทอรีและโคลนโครงการไปยังไดเรกทอรีที่เลือก

เพื่อที่ฉันจะต้องcdแต่ละไดเรกทอรี ( project 1และproject 2) แต่สคริปต์ไม่ได้cdไปที่ไดเรกทอรีที่สองหรือรันคำสั่ง

แต่จะหยุดหลังจากcdและโคลนในproject2ไดเรกทอรี ทำไมมันไม่เรียกcd_project1ฟังก์ชันในรหัสต่อไปนี้

#!/bin/bash
#Get the current user name 

function my_user_name() {        
current_user=$USER
echo " Current user is $current_user"
}

#Creating useful directories

function create_useful_directories() {  
  if [[ ! -d "$scratch" ]]; then
  echo "creating relevant directory"
  mkdir -p /home/"$current_user"/Downloads/scratch/"$current_user"/project1/project2
  else
     echo "scratch directory already exists"
     :
  fi
}

#Going to project2 and cloning 

function cd_project2() {

  cd /home/"$current_user"/Downloads/scratch/"$current_user"/project1/project2 &&
  git clone https://username@bitbucket.org/teamsinspace/documentation-tests.git
  exec bash
}

#Going to project1 directory and cloning 
function cd_project1() {

  cd /home/"$current_user"/Downloads/scratch/"$current_user"/project1/ &&
  git clone https://username@bitbucket.org/teamsinspace/documentation-tests.git
  exec bash

}

#Running the functions  
function main() {

  my_user_name
  create_useful_directories
  cd_project2
  cd_project1    
}
main

ขั้วเอาท์พุท:

~/Downloads$. ./bash_install_script.sh    
Current user is mihi
creating relevant directory
Cloning into 'documentation-tests'...
remote: Counting objects: 125, done.
remote: Compressing objects: 100% (115/115), done.
remote: Total 125 (delta 59), reused 0 (delta 0)
Receiving objects: 100% (125/125), 33.61 KiB | 362.00 KiB/s, done.
Resolving deltas: 100% (59/59), done.
~/Downloads/scratch/mihi/project1/project2$

3
ลองพิจารณายอมรับคำตอบข้อใดข้อหนึ่ง หากมีคำตอบมากกว่าหนึ่งข้อให้ตอบคำถาม - ยอมรับคำตอบที่ดีที่สุดและลงคะแนนอีกข้อ
LeonidMew

1
สวัสดี LeonidMew ขออภัยฉันไม่รู้ว่าจะยอมรับคำตอบได้อย่างไร ทั้งสองคำตอบนั้นดีพอ ๆ กัน
Jenny

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

2
@LeonidMew เพิ่งจะถูกคำถาม 45 นาทีรออีกต่อไปคือ A-OK คำตอบที่ดีกว่าอาจมาพร้อม (เช่นความคิดเห็นของ PerlDuck บอกว่ามันโผล่ขึ้นมาในขณะที่ฉันพิมพ์)
Xen2050

6
ฉันอยากรู้ว่าคุณตั้งใจexec bashจะทำอะไร
หยุดชั่วคราวจนกว่าจะมีการแจ้งให้ทราบต่อไป

คำตอบ:


28

ผู้ร้ายคือexec bashข้อความของคุณในบางหน้าที่ของคุณ execคำสั่งเป็นบิตแปลกและไม่เข้าใจได้ง่ายในสถานที่แรก มันหมายความว่ารันคำสั่งต่อไปนี้แทนของทำงานในขณะนี้คำสั่ง / เชลล์ / script จากที่นี่ นั่นคือมันจะแทนที่เชลล์สคริปต์ปัจจุบัน (ในกรณีของคุณ) ด้วยอินสแตนซ์ของbashและมันจะไม่ส่งคืน

คุณสามารถลองใช้กับเชลล์และปัญหา

exec sleep 5

นี้จะแทนที่เปลือกปัจจุบันคุณ ( bash) มีคำสั่งsleep 5 และเมื่อที่คำสั่งส่งกลับ (หลังจาก 5 วินาที) sleep 5หน้าต่างของคุณจะสนิทเพราะเปลือกได้ถูกแทนที่ด้วย

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

เพียงแค่วางexec bashงบควรทำ


2
@ เจนนี่ดีใจที่ได้ยิน เรื่องเล็ก ๆ น้อย: ภาษา Perl นอกจากนี้ยังมีexecคำสั่งที่มีพฤติกรรมเหมือนกันและถ้าคุณใส่งบบางส่วนหลังจากexecคำสั่ง (ชอบexec something; print "This won't run";) แล้ว Perl จะเตือนคุณว่าprintคำสั่งจะไม่ได้ดำเนินการ
PerlDuck

9
BTW ขอแสดงความยินดีกับการใช้ && หลังจากซีดี (ถ้าคุณไม่ได้ใช้set -e) ฉันได้เห็นรหัสเช่นcd tmp; rm -rf *ล้มเหลวอย่างน่ากลัว
eckes

15

จากhelp exec:

exec: exec [-cl] [-a name] [command [arguments ...]] [redirection ...]
    Replace the shell with the given command.

    Execute COMMAND, replacing this shell with the specified program.
    ARGUMENTS become the arguments to COMMAND.  If COMMAND is not specified,
    any redirections take effect in the current shell.

คำสำคัญที่นี่ถูกแทนที่ - หากคุณexec bashจากภายในสคริปต์จะไม่สามารถดำเนินการสคริปต์ได้อีก


0

หากคุณต้องการกลับไปยังไดเรกทอรีที่คุณเริ่มคุณสามารถใช้

cd -

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

pushd

และกลับไปที่มัน (แม้หลังจากการเปลี่ยนแปลงหลายไดเรกทอรี)

popd

ต้องแน่ใจว่ามีม้าpushdและpopdคำสั่ง


2
ฉันไม่แน่ใจว่าคุณอ่านหรือเข้าใจปัญหาพื้นที่ ไม่มีคำสั่งเหล่านี้จะช่วยให้ผู้ใช้
ท่อ

ฉันไม่สามารถอ่านความจำเป็นในการดำเนินการคำสั่งบางอย่างในเชลล์ ดังนั้นฉันคิดว่าเขาเรียกทุบตีเพื่อกลับไปยังไดเรกทอรีเริ่มต้น หากคุณยืนยันว่าคุณอาจจะพูดว่า: เขาถามถึงสาเหตุของการขาดความต่อเนื่องซึ่งเป็นคำตอบที่สมบูรณ์แบบโดยคำตอบอื่น ๆ
Bernd Wilke πφ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.