Các biến không được truyền từ tập lệnh này gọi tập lệnh khác với Bash heredoc


1

Tôi có một tập lệnh shell được giữ tại người dùng cục bộ của tôi được gọi ( executeAdM.sh ) và khi tôi thực thi tập lệnh này, tôi sẽ chuyển sang người dùng sudo bằng cách nhận lệnh từ tệp hướng dẫn. Nhưng khi tôi thực thi tập lệnh này, tôi cũng truyền các tham số, đây thực sự là một số đường dẫn thư mục của người dùng sudo. Xem kịch bản dưới đây.

Script cho người dùng cục bộ ( executeADM.sh ):

#!/bin/bash
echo password | sudo -S -l
sudo /usr/bin/su - user  <<\EOF
#ls -lrt
pwd
for entry in $(ls -r)
  do
  if [ "$entry" = "testingADM.sh" ];then
    ./"$entry" "$1"
  fi
done
EOF

Tôi đang thực hiện như trên:

./executeADM.sh "/global/u70/globe/ADM"

Khi đoạn script trên thực thi, nó chuyển thành công sang người dùng khác và với người dùng sudo tôi thực thi một for vòng lặp tìm kiếm tập lệnh khác được gọi là testingADM.sh.

Khi tìm thấy tập lệnh, tôi thực thi tập lệnh đó với tham số được truyền từ người dùng cục bộ và testingADM.sh nên đặt đường dẫn cho tôi

Điều này không hoạt động - nó không đọc tham số được truyền từ người dùng cục bộ.

Tập lệnh người dùng sudo ( testingADM.sh ):

#!/bin/bash
changepath=$1
cd "$changepath"
pwd

Khi tôi mã hóa biến đường dẫn trong tập lệnh, tất cả đều hoạt động tốt. Nhưng tôi không muốn điều đó:

 #!/bin/bash
 changepath=somepath
 cd "$changepath"
 pwd

Vấn đề là thay vì đi đến "/global/u70/globe/ADM" nó đi theo con đường như "/global/u70/globe/", Đó là con đường sau khi tôi làm sudo. Nó chỉ là không vượt qua biến.


Với những gợi ý dưới đây, đây là những gì tôi đã kết thúc với:

#!/bin/bash
echo password | sudo -S -l
sudo /usr/bin/su - user  <<EOF
#ls -lrt
#pwd
echo "$1"
./testingADM.sh "$1"
EOF

Các echo lệnh in không có gì; một không gian trống được hiển thị. Nó hoạt động khi tôi thay đổi \EOF đến EOF.

Bất cứ ai có thể giải thích sự khác biệt giữa:

\EOF , "EOF" , 'EOF' , EOF

hoặc làm ba cái đầu tiên có cùng ý nghĩa? Vậy thì sự khác biệt giữa chúng là gì?


Xin đừng thay đổi câu hỏi của bạn sau khi bạn nhận được câu trả lời giải quyết vấn đề của bạn. Khi một câu hỏi được trả lời, thật khó hiểu nếu nó được thay đổi hoặc có bổ sung sau đó. Nếu bạn có thêm câu hỏi, tốt hơn là giải quyết chúng trong các bình luận hoặc hỏi một câu hỏi hoàn toàn mới.
slhck

@slhck có quan điểm của bạn vì vậy bây giờ bạn có thể cho tôi biết lý do trong phần bình luận không?
Tushar Sharma

Tôi không chắc mình có thể trả lời câu hỏi này mà không có một số ví dụ cụ thể, xem những gì bạn đã thử và tại sao nó không hiệu quả với bạn. Vì vậy, xin vui lòng hỏi một câu hỏi mới về nó. Cảm ơn!
slhck

Okk không có vấn đề tôi sẽ gửi một câu hỏi mới.
Tushar Sharma

Câu trả lời:


1

Không trích dẫn hoặc thoát khỏi chuỗi giới hạn di truyền của bạn (nghĩa là sử dụng EOF thay vì \EOF hoặc là "EOF" ), nếu không, các biến đặc biệt như $ sẽ không được giải thích. Xem đây để biết thêm thông tin và ví dụ (ví dụ: Ví dụ 19-7).

Đây là một kịch bản tối thiểu hoạt động:

$ cat test.sh
#!/bin/bash
sudo su - $(whoami) <<EOF
./test2.sh "$1"
EOF

$ cat test2.sh
#!/bin/bash
foo=$1
echo "$foo"

$ ./test1.sh "/path/to/file"
"/path/to/file"

Lưu ý rằng:

  • Không cần cho các di sản cả. Chỉ cần gọi ./test2.sh trực tiếp sau sudo: sudo -u $(whoami) test2.sh "$1"
  • Bạn không nên lặp qua đầu ra của ls.
  • Không cần phải làm một for vòng lặp để tìm kiếm một tập tin duy nhất. Chỉ cần gọi kịch bản trực tiếp với tên của nó.

Bạn cũng nên trích dẫn các biến của mình, đó là:

  • Thực thi tập lệnh của bạn với ./executeADM.sh "/path/with white/space"
  • Gọi điện ./"$entry" "$1" trong kịch bản của bạn
  • Trong tập lệnh khác của bạn, sử dụng cd "$path"

Nói chung:

  • Luôn luôn trích dẫn các biến. (Đừng trích dẫn chúng - chúng sẽ không mở rộng.)
  • Đừng sử dụng một biến được gọi là path. (Nhiều như bạn sẽ không sử dụng các biến được gọi là user, home, v.v.)

tôi cập nhật câu trả lời của tôi với đường dẫn tôi đang cung cấp.
Tushar Sharma

Vì vậy khi bạn echo "$changepath", nó là /global/u70/globe/ và không /global/u70/globe/ADM? Điều đó khá lạ.
slhck

@slhck: thật là kỳ lạ.
tukan

@slhck chính xác bạn có phải là do truyền tham số từ cục bộ và đọc sau khi sudo với EOF? Có thể là nó không gửi tham số ??
Tushar Sharma

@tukan đúng vậy, và tôi nghĩ EOF không đọc tham số.
Tushar Sharma

1

Chỉnh sửa
Từ phía sau đầu tôi. Con đường của bạn có chứa không gian?

Nếu có, bạn cần phải thực hiện nó như là ./executeADM.sh 'somePath'.

Luôn luôn tốt hơn để tiết kiệm $1 vào một biến khi bạn chuyển nó đi xa hơn nó làm cho nó dễ đọc hơn. Tôi sẽ thêm path=$1 sau đó trong tập tin lô bạn sẽ có ./$entry "$path"


./$entry '$path' sẽ không mở rộng biến nhưng vượt qua nó theo nghĩa đen $path.
slhck

@slhck: bạn nói đúng. Tôi đã chỉnh sửa câu trả lời để có dấu ngoặc kép - để mở rộng. Đường dẫn đầu tiên có thể là với các trích dẫn đơn ở đó bạn không cần bất kỳ sự mở rộng nào.
tukan

Mặc dù như bạn có thể thấy trong bản cập nhật của OP cho câu hỏi, đó không phải là vấn đề.
slhck

@slhck: ah đã bỏ lỡ điều đó, sẽ kiểm tra xem. Cảm ơn các cập nhật.
tukan

@tukan cảm ơn sự giúp đỡ và thời gian của bạn cũng xin lỗi tôi đã trả lời muộn.
Tushar Sharma
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.