GNU/Linux >> Belajar Linux >  >> Linux

Apa perbedaan antara menggunakan `sh` dan `source`?

Perbedaan utamanya adalah mereka dieksekusi dalam proses yang berbeda.

Jadi jika Anda source file foo yang melakukan cd , shell sumber (misalnya shell interaktif Anda di terminal) terpengaruh (dan direktori saat ini akan berubah)

Jika Anda menjalankan sh foo cd tidak memengaruhi shell sumber, hanya sh yang baru dibuat proses menjalankan foo

Baca Panduan Pembuatan Skrip Bash Tingkat Lanjut.


Seperti yang telah disebutkan orang lain, saat Anda menjalankan sh test.sh , setiap perubahan yang test.sh membuat ke lingkungan shell Anda tidak akan bertahan setelah proses berakhir.

Namun, perhatikan juga bahwa setiap elemen lingkungan Anda yang tidak diekspor (misalnya, variabel, alias, dan fungsi shell) tidak akan tersedia untuk kode di test.sh ketika dijalankan sebagai subproses (yaitu dengan sh test.sh ).

Misalnya:

$ cat > test.sh
echo $foo
$ foo=bar
$ sh test.sh
$ . test.sh
bar

Contoh 2:

[email protected]:~$ cat test.sh
#!/bin/sh
cd /etc
[email protected]:~$ sh test.sh 
[email protected]:~$ pwd
/home/savoury
[email protected]:~$ source test.sh 
[email protected]:/etc$ pwd
/etc
[email protected]:/etc$ 

Saat Anda memanggil source atau . (yang satu adalah alias dari yang lain. source cmd bukan POSIX - semacam bashism ), Anda memuat dan menjalankan skrip shell ke dalam arus proses shell . Jadi Anda bisa

  • baca variabel yang diatur dalam skrip bersumber,
  • gunakan fungsi yang ditentukan di dalamnya.
  • dan bahkan jalankan fork dan/atau subproses jika skrip melakukan ini.

Saat Anda memanggil sh , Anda memulai garpu (sub-proses atau anak ) yang menjalankan sesi baru /bin/sh (yang sering berupa tautan simbolis ke bash ). Dalam hal ini, variabel lingkungan yang disetel oleh subskrip akan dihapus saat subskrip dihentikan.

Perhatian :sh bisa menjadi symlink ke lain cangkang.

Contoh praktis

Misalnya, jika Anda ingin mengubah direktori kerja saat ini dengan cara tertentu, Anda tidak dapat melakukannya

$ cat <<eof >myCd2Doc.sh
#!/bin/sh
cd /usr/share/doc
eof

$ chmod +x myCd2Doc.sh

Ini tidak akan melakukan apa yang Anda harapkan:

$ cd /tmp
$ pwd
/tmp
$ ~/myCd2Doc.sh
$ pwd
/tmp

karena direktori kerja saat ini adalah bagian dari lingkungan dan myCd2Doc.sh akan berjalan di subkulit .

Tapi:

$ cat >myCd2Doc.source <<eof
# Shell source file
myCd2Doc() {
    cd /usr/share/doc
}
eof

$ . myCd2Doc.source
$ cd /tmp
$ pwd
/tmp
$ myCd2Doc
$ pwd
/usr/share/doc

Lihat mycd fungsi!! (Dengan penyelesaian bash berdasarkan Associative Array ).

Tingkat eksekusi $SHLVL

$ cd /tmp
printf %b '\43\41/bin/bash\necho This is level \44SHLVL.\n' >qlvl.sh

$ bash qlvl.sh 
This is level 2.

$ source qlvl.sh 
This is level 1.

Rekursi (saat skrip dijalankan dari dirinya sendiri)

$ cat <<eoqlvl2 >qlvl2.sh 
#!/bin/bash

export startLevel recursionLimit=5
echo This is level $SHLVL started:${startLevel:=$SHLVL}.
(( SHLVL < recursionLimit )) && ./qlvl2.sh
eoqlvl2
$ chmod +x qlvl2.sh

$ ./qlvl2.sh 
This is level 2 started:2.
This is level 3 started:2.
This is level 4 started:2.
This is level 5 started:2.

$ source qlv2.sh 
This is level 1 started:1.
This is level 2 started:1.
This is level 3 started:1.
This is level 4 started:1.
This is level 5 started:1.

Sedikit lagi

$ sed '$a ps --sid $SID fw' qlvl.sh >qlvl3.sh
$ chmod +x qlvl3.sh 
$ export SID
$ read SID < <(ps ho sid $$)
$ echo $SID $$
8983 8983

( PID saat ini ($$ ==Id proses ) adalah pengenal yang sama dengan SID (ID sesi ). Itu tidak selalu benar.)

$ ./qlvl3.sh 
This is level 2.
  PID TTY      STAT   TIME COMMAND
 8983 pts/10   Ss     0:00 /bin/bash
10266 pts/10   S+     0:00  \_ /bin/bash ./qlvl3.sh
10267 pts/10   R+     0:00      \_ ps --sid 8983 fw

$ . qlvl3.sh 
This is level 1.
  PID TTY      STAT   TIME COMMAND
 8983 pts/10   Ss     0:00 /bin/bash
10428 pts/10   R+     0:00  \_ ps --sid 8983 fw

Titik . adalah alias dari source . Jadi satu-satunya perbedaan antara dua perintah adalah slash diganti dengan space .

Dan final tes:

$ printf %b '\43\41/bin/bash\necho Ending this.\nsle' \
    'ep 1;exit 0\n' >finalTest.sh

$ bash finalTest.sh 
Ending this.

$ source finalTest.sh
Ending this.

... Anda mungkin melihat berbeda perilaku antara dua sintaks.;-)


Linux
  1. Apa perbedaan antara Redhat dan centOS?

  2. Apa perbedaan antara strtok_r dan strtok_s di C?

  3. Apa perbedaan antara fsck dan e2fsck?

  1. Apa perbedaan antara adduser dan useradd?

  2. Apa perbedaan antara `su -` dan` su --login`?

  3. Apa perbedaan antara unlink dan rm?

  1. Apa perbedaan antara InnoDB dan MyISAM?

  2. Perbedaan Antara [[ $a ==Z* ]] Dan [ $a ==Z* ]?

  3. Apa perbedaan antara rute dan rute ip?