Tại sao không sử dụng hai lệnh cd trong tập lệnh bash thực thi lệnh thứ hai?


15

Tôi đã viết một tập lệnh bash tạo ra một loạt các thư mục và sao chép một dự án vào các thư mục được chọn.

Đối với điều đó, tôi cần đến cdtừng thư mục ( project 1project 2), nhưng tập lệnh không cdđến thư mục thứ hai cũng không thực thi lệnh.

Thay vào đó, nó dừng lại sau cdvà nhân bản trong project2thư mục. Tại sao nó không gọi cd_project1hàm trong đoạn mã sau?

#!/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

Đầu ra thiết bị đầu cuối:

~/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
Xem xét chấp nhận một trong những câu trả lời. Nếu có nhiều câu trả lời là một giải pháp cho một câu hỏi - hãy chấp nhận câu trả lời hay nhất và bỏ phiếu khác.
LeonidMew

1
Xin chào LeonidMew. Xin lỗi tôi không biết làm thế nào để chấp nhận câu trả lời. Cả hai câu trả lời đều tốt như nhau.
Jenny

5
@Jenny, đừng cảm thấy vội vàng. Đọc Tôi nên làm gì khi ai đó trả lời câu hỏi của tôi? thay vào đó và hành động phù hợp khi bạn hài lòng . Chỉ cần dành thời gian của bạn, không có lý do để vội vàng. Hoàn toàn ổn nếu bạn quyết định trong một ngày hoặc trong một tuần hoặc bất cứ lúc nào.
PerlDuck

2
@LeonidMew mới chỉ 45 phút kể từ khi câu hỏi được hỏi, chờ đợi lâu hơn là A-OK, một câu trả lời tốt hơn thậm chí có thể xuất hiện (như nhận xét của PerlDuck nói, nó chỉ bật lên trong khi tôi đang gõ)
Xen2050

6
Tôi tò mò không biết bạn dự định exec bashlàm gì.
Tạm dừng cho đến khi có thông báo mới.

Câu trả lời:


28

Thủ phạm là exec bashtuyên bố của bạn trong một số chức năng của bạn. Các exectuyên bố là một chút kỳ lạ và không dễ hiểu ở nơi đầu tiên. Nó có nghĩa là: thực hiện lệnh sau thay vì lệnh / shell / script hiện đang chạy từ đây về sau . Đó là: nó thay thế tập lệnh shell hiện tại (trong trường hợp của bạn) bằng một thể hiện bashvà nó không bao giờ trả về.

Bạn có thể thử điều này với một vỏ và vấn đề

exec sleep 5

Điều này sẽ thay thế shell hiện tại của bạn (lệnh bash) bằng lệnh sleep 5 và khi lệnh đó trở lại (sau 5 giây), cửa sổ của bạn sẽ đóng lại vì shell đã được thay thế bằng sleep 5.

Tương tự với tập lệnh của bạn: Nếu bạn đưa exec somethingvào tập lệnh của mình, tập lệnh sẽ được thay thế bằng somethingvà khi điều đó somethingdừng thực thi, toàn bộ tập lệnh sẽ dừng lại.

Đơn giản chỉ cần bỏ các exec bashtuyên bố nên làm.


2
@Jenny Rất vui được nghe. Giai thoại: Ngôn ngữ Perl cũng có một execcâu lệnh có hành vi tương tự và nếu bạn đặt một số câu sau một execcâu lệnh (như exec something; print "This won't run";) thì Perl sẽ cảnh báo bạn rằng printcâu lệnh sẽ không bao giờ được thực thi.
PerlDuck

9
BTW chúc mừng bạn đã sử dụng && sau cd, (nếu bạn không sử dụng set -e). Tôi đã thấy Code như cd tmp; rm -rf *thất bại kinh khủng
eckes 15/03/19

15

Từ 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.

Từ khóa ở đây là thay thế - nếu bạn exec bashtừ bên trong một tập lệnh, không thể thực hiện thêm tập lệnh nào nữa.


0

nếu bạn muốn quay trở lại thư mục bạn đã bắt đầu, bạn có thể sử dụng

cd -

Nhưng nếu bạn không chắc chắn liệu một cdlệnh có được thực thi hay không thì tốt hơn là sử dụng các lệnh để đặt các thư mục làm việc lên một ngăn xếp:

pushd

và quay lại nó (ngay cả sau khi nhiều thư mục thay đổi)

popd

hãy chắc chắn để có đẳng thức pushdpopdlệnh.


2
Tôi không chắc bạn đã đọc hoặc hiểu không gian vấn đề. Không có lệnh nào trong số này sẽ giúp người dùng.
ống

Tôi không nơi nào có thể đọc được sự cần thiết phải thực thi một số lệnh trong shell. Vì vậy, tôi nghĩ rằng anh ấy đã gọi bash để quay lại thư mục bắt đầu. Nếu bạn khăng khăng bạn có thể nói: anh ấy hỏi lý do của sự tiếp tục bị mất, được trả lời hoàn hảo bởi các câu trả lời khác.
Bernd Wilke πφ 17/03/19
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.