Truyền biến cho tập lệnh bash khi tìm nguồn


18

Giả sử tôi có trong main.sh:

$NAME="a string"
if [ -f $HOME/install.sh ]
    . $HOME/install.sh $NAME
fi

và trong install.sh:

echo $1

Điều này được cho là vang "a string", nhưng nó không có gì. Tại sao?


2
Đừng cập nhật câu hỏi. Bằng cách này, chúng tôi không thể thấy những gì sai với câu hỏi ban đầu của bạn. Tôi chỉ cần cuộn nó lại.
Valentin Bajrami

Câu trả lời:


20

Michael Mrozek bao gồm hầu hết các vấn đề và các bản sửa lỗi của anh ấy sẽ hoạt động vì bạn đang sử dụng Bash.

Bạn có thể quan tâm đến thực tế rằng khả năng tìm kiếm một kịch bản với các đối số là một bashism. Trong shhoặc dashcủa bạn main.shsẽ không lặp lại bất cứ điều gì vì các đối số cho tập lệnh có nguồn gốc bị bỏ qua và $1sẽ đề cập đến đối số đểmain.sh.

Khi bạn nhập tập lệnh vào sh, như thể bạn chỉ sao chép và dán văn bản của tập lệnh có nguồn gốc vào tập tin mà nó được lấy nguồn. Hãy xem xét những điều sau (lưu ý, tôi đã thực hiện chỉnh sửa mà Michael khuyến nghị):

$ bash ./test.sh
A String
$ sh ./test.sh

$ sh ./test.sh "HELLO WORLD"
HELLO WORLD

"Trong sh hoặc dash main.sh của bạn sẽ không lặp lại bất cứ điều gì vì các đối số cho tập lệnh có nguồn gốc bị bỏ qua và $ 1 sẽ đề cập đến đối số cho main.sh" Đó chính xác là những gì đang xảy ra. Cảm ơn đã trả lời.
Ai đó vẫn sử dụng bạn MS-DOS

Tôi đã đánh dấu câu trả lời của bạn là được chấp nhận, bởi vì vấn đề thực sự không phải là lỗi trong kịch bản của tôi, mà chủ yếu là vì tôi đã đánh đồng sh với bash, và bash thực hiện công việc kém khi mô phỏng sh trong tình huống này. Câu trả lời của bạn đã làm tôi lo lắng về vấn đề này, cảm ơn;
Ai đó vẫn sử dụng bạn MS-DOS

2
Về mặt kỹ thuật, đây là một chủ nghĩa kshism ở đây (đã có trong ksh86, có thể sớm hơn). @ SomebodystillusesyouMS-DOS, đặc tả "sh" không cho biết điều gì sẽ xảy ra nếu bạn vượt qua các đối số bổ sung, do đó, hành vi dấu gạch ngang hoặc bash không khác gì "sh" so với cái kia và có giá trị như nhau.
Stéphane Chazelas

16

Tôi thấy ba lỗi:

  1. Dòng bài tập của bạn sai:

    $NAME="a string"

    Khi bạn gán cho một biến bạn không bao gồm $; nó nên là:

    NAME="a string"
  2. Bạn đang mất tích then; dòng điều kiện nên là:

    if [ -f $HOME/install.sh ]; then
  3. Bạn không trích dẫn $NAME, mặc dù nó có không gian. Dòng nguồn phải là:

    . $HOME/install.sh "$NAME"

Anh ấy cũng có một vài lỗi khác, nhưng tôi không nghĩ đó là nguyên nhân của vấn đề mà anh ấy đưa ra.
Steven D

@Steven Bạn nói đúng, có một vài điều tôi không đề cập đến; nó hoạt động với tôi với các bản sửa lỗi tôi đã liệt kê ngay bây giờ
Michael Mrozek

@Steven Khi tôi cùng nhau viết kịch bản để thử nó, tôi đã viết tắt nó thành [ -f $HOME/install.sh ] && . $HOME/install.sh $NAME; Tôi có lẽ không nên làm những việc như vậy khi tôi đang tìm kiếm lỗi
Michael Mrozek

Có vẻ như vấn đề khác tôi nghĩ là thực sự không có vấn đề gì vì anh ấy đặc biệt đề cập đến BASH.
Steven D

5

chỉ cần đặt tham số của bạn trước khi tìm nguồn cung cấp tập lệnh!

chính

#!/bin/bash
NAME=${*:-"a string"}
if [[ -f install.sh ]];
then
    set -- $NAME ;
    . install.sh ;
fi
exit;

cài đặt

#!/bin/bash
echo  " i am sourced by [ ${0##*/} ]";
echo  " with [ $@ ] as parametr(s) ";
exit;

kiểm tra

u@h$ ./main.sh some args
 i am sourced by [ main.sh ]
 with [ some args ] as parametr(s) 
u@h$

Làm thế nào để bạn đặt cờ?
Jonathan Landrum

Chỉnh sửa: bạn dường như chỉ xâu chuỗi chúng sau khi chúng --giống như các đối số lệnh:set -- -v foo -l bar -j "${bin}"
Jonathan Landrum
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.