Melewati variabel ke skrip bash saat mengambilnya

18

Misalkan saya ada di main.sh:

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

dan di install.sh:

echo $1

Ini seharusnya bergema "a string", tetapi tidak ada gema. Mengapa?

Seseorang masih menggunakan Anda MS-DOS
sumber
2
Tolong jangan memperbarui pertanyaannya. Dengan cara ini kami tidak dapat melihat apa yang salah dengan pertanyaan awal Anda. Saya baru saja mengembalikannya.
Valentin Bajrami

Jawaban:

20

Michael Mrozek mencakup sebagian besar masalah dan perbaikannya akan berhasil karena Anda menggunakan Bash.

Anda mungkin tertarik pada kenyataan bahwa kemampuan untuk sumber naskah dengan argumen adalah bashism. Dalam shatau dashAnda main.shtidak akan menggemakan apa pun karena argumen ke skrip bersumber diabaikan dan $1akan merujuk pada argumen untukmain.sh.

Ketika Anda sumber skrip sh, seolah-olah Anda hanya menyalin dan menempelkan teks dari skrip bersumber ke file dari mana itu berasal. Pertimbangkan yang berikut ini (catatan, saya telah membuat koreksi yang direkomendasikan Michael):

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

$ sh ./test.sh "HELLO WORLD"
HELLO WORLD
Steven D
sumber
"Di sh atau dash main.sh Anda tidak akan menggemakan apa pun karena argumen ke skrip bersumber diabaikan dan $ 1 akan merujuk pada argumen ke main.sh" Itulah yang terjadi. Terimakasih telah menjawab.
Seseorang masih menggunakan Anda MS-DOS
Saya menandai jawaban Anda sebagai diterima, karena masalah sebenarnya bukan dengan kesalahan dalam skrip saya, tetapi terutama karena saya menyamakan sh dengan bash, dan bash melakukan pekerjaan yang buruk dalam meniru sh dalam situasi ini. Jawaban Anda membuat saya bersemangat tentang masalah ini, terima kasih;
Seseorang masih menggunakan Anda MS-DOS
2
Secara teknis, ini lebih merupakan kshisme di sini (sudah ada di ksh86, mungkin sebelumnya). @ SomebodystillusesyouMS-DOS, spesifikasi "sh" tidak mengatakan apa yang harus terjadi jika Anda memberikan argumen tambahan, sehingga perilaku dash atau bash tidak lebih "sh" dari yang lain dan sama-sama valid.
Stéphane Chazelas
16

Saya melihat tiga kesalahan:

  1. Baris tugas Anda salah:

    $NAME="a string"

    Saat Anda menetapkan variabel Anda tidak menyertakan $; harus:

    NAME="a string"
  2. Kamu hilang then; baris kondisional harus:

    if [ -f $HOME/install.sh ]; then
  3. Anda tidak mengutip $NAME, meskipun memiliki spasi. Baris sumber harus:

    . $HOME/install.sh "$NAME"
Michael Mrozek
sumber
Dia juga memiliki beberapa kesalahan lain, tetapi saya pikir itu bukan sumber masalah yang dia kemukakan.
Steven D
@ Seven Kau benar, ada beberapa lagi yang tidak kusebutkan; itu bekerja untuk saya dengan perbaikan yang saya daftarkan sekarang
Michael Mrozek
@ Seven Ketika saya sedang menyusun skrip untuk mencobanya, saya menyingkatnya menjadi [ -f $HOME/install.sh ] && . $HOME/install.sh $NAME; Saya mungkin tidak boleh melakukan hal-hal seperti itu ketika saya mencari kesalahan
Michael Mrozek
Sepertinya masalah lain yang saya pikir sebenarnya tidak ada masalah karena dia secara khusus menyebutkan BASH.
Steven D
5

cukup atur parameter Anda sebelum mengambil skrip!

main.sh

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

install.sh

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

uji

u@h$ ./main.sh some args
 i am sourced by [ main.sh ]
 with [ some args ] as parametr(s) 
u@h$
Jonah
sumber
Bagaimana Anda mengatur bendera?
Jonathan Landrum
Sunting: Anda tampaknya hanya merangkai mereka --seperti mereka adalah argumen perintah:set -- -v foo -l bar -j "${bin}"
Jonathan Landrum