xác định đường dẫn đến tập lệnh shell có nguồn gốc


80

Có cách nào để một kịch bản shell có nguồn gốc tìm ra đường dẫn đến chính nó không? Tôi chủ yếu quan tâm đến bash, mặc dù tôi có một số đồng nghiệp sử dụng tcsh.

Tôi đoán rằng tôi có thể không có nhiều may mắn ở đây, vì việc tìm nguồn cung ứng khiến các lệnh được thực thi trong trình bao hiện tại, do đó $0vẫn là lời gọi của trình bao hiện tại, không phải là tập lệnh có nguồn gốc. Suy nghĩ tốt nhất của tôi hiện tại là phải làm source $script $script, để tham số vị trí đầu tiên chứa thông tin cần thiết. Bất cứ ai có một cách tốt hơn?

Để rõ ràng, tôi đang tìm nguồn cung cấp kịch bản, không chạy nó:

source foo.bash

câu hỏi liên quan có hơn 4200 lượt upvote: stackoverflow.com/q/59895/52074
Trevor Boyd Smith

Câu trả lời:


65

Trong tcsh, $_vào lúc bắt đầu của kịch bản sẽ chứa các vị trí nếu tập tin đã có nguồn gốc và $0chứa nó nếu nó được chạy.

#!/bin/tcsh
set sourced=($_)
if ("$sourced" != "") then
    echo "sourced $sourced[2]"
endif
if ("$0" != "tcsh") then
    echo "run $0"
endif

Trong Bash:

#!/bin/bash
[[ $0 != $BASH_SOURCE ]] && echo "Script is being sourced" || echo "Script is being run"

Tôi chỉ có dịp sử dụng cái này trong tcsh, và nhận thấy rằng nó không hoạt động nếu không có shebang. Có vẻ hơi kỳ lạ khi hành vi thay đổi nếu bạn chỉ tìm nguồn cung ứng, không thực hiện nó ...
Cascabel

Phiên bản tcsh dường như cũng không hoạt động nếu tập lệnh có nguồn gốc không tương tác (ví dụ từ một cshrc). Tôi dường như không thể tìm ra cách để có được thông tin trong trường hợp đó. Có suy nghĩ gì không?
Cascabel

Tìm nguồn cung ứng cho tôi mà không cần shebang. > tcsh --version\n tcsh 6.14.00 (Astron) 2005-03-25 (i486-intel-linux) options wide,nls,dl,al,kan,rh,nd,color,filec. Theo như tìm nguồn cung ứng không tương tác, tệp nguồn được đưa vào tệp cha như thể nó thực sự là một phần của nó (không thể phân biệt như vậy) như bạn đề cập trong câu hỏi ban đầu của mình. Tôi nghĩ rằng cách giải quyết tham số vị trí của bạn có lẽ là cách tiếp cận tốt nhất. Tuy nhiên, câu hỏi thông thường là "tại sao bạn muốn làm điều đó" và câu trả lời thông thường cho câu trả lời là "đừng làm điều đó - hãy làm điều này thay vì" nơi "này" thường được lưu trữ ...
Dennis Williamson

2
@clacke: Tôi thấy rằng trong tất cả các phiên bản Bash mà tôi đã thử nghiệm từ 2.05b đến 4.2.37, bao gồm 4.1.9, .sourceđã hoạt động giống hệt nhau về vấn đề này. Lưu ý rằng $_phải được truy cập trong câu lệnh đầu tiên trong tệp, nếu không nó sẽ chứa đối số cuối cùng của lệnh trước đó. Tôi muốn bao gồm shebang cho tài liệu tham khảo của riêng tôi để tôi biết nó nên dùng cho trình soạn thảo nào và cho trình soạn thảo để nó sử dụng tô sáng cú pháp.
Dennis Williamson

1
Haha. Rõ ràng tôi đã thử nghiệm bằng cách làm trước source, sau đó làm .. Tôi xin lỗi vì không đủ năng lực. Họ thực sự giống hệt nhau. Dù sao, $BASH_SOURCEcông trình.
clacke

30

Tôi nghĩ rằng bạn có thể sử dụng $BASH_SOURCEbiến. Nó trả về đường dẫn đã được thực thi:

pbm@tauri ~ $ /home/pbm/a.sh 
/home/pbm/a.sh
pbm@tauri ~ $ ./a.sh
./a.sh
pbm@tauri ~ $ source /home/pbm/a.sh 
/home/pbm/a.sh
pbm@tauri ~ $ source ./a.sh
./a.sh

Vì vậy, trong bước tiếp theo chúng ta nên kiểm tra xem đường dẫn có tương đối hay không. Nếu nó không tương đối thì mọi thứ đều ổn. Nếu đó là chúng ta có thể kiểm tra đường dẫn với pwd, nối với /$BASH_SOURCE.


2
Và lưu ý rằng sourcecác tìm kiếm trong $PATHnếu tên đã cho không chứa a /. Thứ tự tìm kiếm phụ thuộc vào tùy chọn shell, tham khảo hướng dẫn để biết chi tiết.
Gilles

1
Vì vậy, một cái gì đó như mydir="$(cd "$(dirname "$BASH_SOURCE")"; pwd)"sẽ làm việc?
Kevin Cantu

Cảm ơn, một câu trả lời nhanh chóng và hữu ích. Dennis giành được dấu kiểm màu xanh lá cây để đưa ra câu trả lời tcsh. @Gilles: Phải, tôi đã tìm thấy điều đó trong tài liệu. May mắn cho trường hợp sử dụng của tôi, tôi gần như chắc chắn không phải lo lắng về nó.
Cascabel

18

Đối với sự thấu đáo và vì lợi ích của người tìm kiếm, đây là những gì họ làm ... Đây là một wiki cộng đồng, vì vậy hãy thoải mái thêm các tương đương của shell khác (rõ ràng, $ BASH_SOURCE sẽ khác).

kiểm tra

#! /bin/sh
called=$_
echo $called
echo $_
echo $0
echo $BASH_SOURCE

test2.sh:

#! /bin/sh
source ./test.sh

Bash:

$./test2.sh
./test2.sh
./test2.sh
./test2.sh
./test.sh
$ sh ./test2.sh
/bin/sh
/bin/sh
./test2.sh
./test.sh

Dấu gạch ngang

$./test2.sh
./test2.sh
./test2.sh
./test2.sh

$/bin/sh ./test2.sh
/bin/sh
/bin/sh
./test2.sh

$

Zsh

$ ./test2.sh
./test.sh
./test.sh
./test.sh

$ zsh test.sh

echo
test.sh

$

1
Tôi không hiểu: tại sao called=$_; echo $called; echo $_? Đây không phải là in $_hai lần?
Ciro Santilli 新疆 心 心

5
@CiroSantilli: Không phải lúc nào cũng vậy, hãy đọc hướng dẫn Bash về $_tham số đặc biệt: "Khi khởi động shell, được đặt thành tên đường dẫn tuyệt đối được sử dụng để gọi shell hoặc shell script được thực thi như được truyền trong môi trường hoặc danh sách đối số. Sau đó, mở rộng đến cuối cùng đối số với lệnh trước, sau khi mở rộng. Cũng được đặt thành tên đường dẫn đầy đủ được sử dụng để gọi từng lệnh được thực thi và được đặt trong môi trường được xuất sang lệnh đó. Khi kiểm tra thư, tham số này giữ tên của tệp thư. "
Adam Rosenfield

Vấn đề với điều này là tập tin có nguồn gốc có tiêu đề #! /bin/shlàm cho nó vô dụng với nguồn. Điều đó sẽ bắt đầu một thể hiện mới của /bin/sh, đặt các biến, sau đó thoát khỏi thể hiện đó, giữ nguyên thể gọi.
JamesThomasMoon1979

2
@ JamesThomasMoon1979: Bạn đang nói về cái gì? Bất cứ điều gì bắt đầu với #một kịch bản shell là một nhận xét.  #!(shebang) chỉ có ý nghĩa đặc biệt là dòng đầu tiên của tập lệnh được thực thi.   Là dòng đầu tiên của một tệp có nguồn gốc, nó chỉ là một nhận xét.
Scott

17

Giải pháp này chỉ áp dụng cho bash và không tcsh. Lưu ý rằng câu trả lời thường được cung cấp ${BASH_SOURCE[0]}sẽ không hoạt động nếu bạn cố gắng tìm đường dẫn từ bên trong một hàm.

Tôi đã tìm thấy dòng này luôn hoạt động, bất kể tập tin đang được lấy nguồn hay chạy dưới dạng tập lệnh.

echo ${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}

Nếu bạn muốn theo dõi các liên kết tượng trưng sử dụng readlinktrên con đường bạn đi ở trên, đệ quy hoặc không đệ quy.

Đây là một kịch bản để dùng thử và so sánh nó với các giải pháp được đề xuất khác. Gọi nó là source test1/test2/test_script.shhoặc bash test1/test2/test_script.sh.

#
# Location: test1/test2/test_script.sh
#
echo $0
echo $_
echo ${BASH_SOURCE}
echo ${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}

cur_file="${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}"
cur_dir="$(dirname "${cur_file}")"
source "${cur_dir}/func_def.sh"

function test_within_func_inside {
    echo ${BASH_SOURCE}
    echo ${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}
}

echo "Testing within function inside"
test_within_func_inside

echo "Testing within function outside"
test_within_func_outside

#
# Location: test1/test2/func_def.sh
#
function test_within_func_outside {
    echo ${BASH_SOURCE}
    echo ${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}
}

Lý do các công việc một lớp được giải thích bằng việc sử dụng BASH_SOURCEbiến môi trường và liên kết của nó FUNCNAME.

BASH_SOURCE

Một biến mảng có thành viên là tên tệp nguồn trong đó tên hàm shell tương ứng trong biến mảng FUNCNAME được xác định. Hàm shell $ {FUNCNAME [$ i]} được xác định trong tệp $ {BASH_SOURCE [$ i]} và được gọi từ $ {BASH_SOURCE [$ i + 1]}.

FUNCNAME

Một biến mảng chứa tên của tất cả các hàm shell hiện có trong ngăn xếp lệnh thực thi. Phần tử có chỉ số 0 là tên của bất kỳ hàm shell nào đang thực thi. Phần tử dưới cùng nhất (phần tử có chỉ số cao nhất) là "chính". Biến này chỉ tồn tại khi một hàm shell đang thực thi. Việc gán cho FUNCNAME không có hiệu lực và trả về trạng thái lỗi. Nếu FUNCNAME không được đặt, nó sẽ mất các thuộc tính đặc biệt, ngay cả khi sau đó được đặt lại.

Biến này có thể được sử dụng với BASH_LINENO và BASH_SOURCE. Mỗi phần tử của FUNCNAME có các phần tử tương ứng trong BASH_LINENO và BASH_SOURCE để mô tả ngăn xếp cuộc gọi. Chẳng hạn, $ {FUNCNAME [$ i]} đã được gọi từ tệp $ {BASH_SOURCE [$ i + 1]} tại số dòng $ {BASH_LINENO [$ i]}. Trình dựng cuộc gọi hiển thị ngăn xếp cuộc gọi hiện tại bằng cách sử dụng thông tin này.

[Nguồn: hướng dẫn Bash]


Giải pháp này hiệu quả với tôi trong bash trong khi câu trả lời được chọn chỉ hoạt động không liên tục. Tôi chưa bao giờ hiểu tại sao đôi khi nó hoạt động mà không phải là những người khác (có lẽ tôi đã không chú ý đúng mức đến vỏ tìm nguồn cung ứng).
Jim2B

13

Điều này làm việc cho tôi trong bash, dash, ksh và zsh:

if test -n "$BASH" ; then script=$BASH_SOURCE
elif test -n "$TMOUT"; then script=${.sh.file}
elif test -n "$ZSH_NAME" ; then script=${(%):-%x}
elif test ${0##*/} = dash; then x=$(lsof -p $$ -Fn0 | tail -1); script=${x#n}
else script=$0
fi

echo $script

Đầu ra cho các shell này:

BASH source: ./myscript
ZSH source: ./myscript
KSH source: /home/pbrannan/git/theme/src/theme/web/myscript
DASH source: /home/pbrannan/git/theme/src/theme/web/myscript
BASH: ./myscript
ZSH: ./myscript
KSH: /home/pbrannan/git/theme/src/theme/web/myscript
DASH: ./myscript

Tôi đã cố gắng làm cho nó hoạt động cho csh / tcsh, nhưng nó quá khó; Tôi đang gắn bó với POSIX.


1

Tôi đã có một chút bối rối bởi câu trả lời wiki cộng đồng (từ Shawn J. Goff), vì vậy tôi đã viết một kịch bản để sắp xếp mọi thứ. Về $_, tôi đã tìm thấy điều này: Cách sử dụng _như một biến môi trường được truyền cho một lệnh . Đây là một biến môi trường để dễ dàng kiểm tra giá trị của nó không chính xác.

Dưới đây là kịch bản, sau đó là đầu ra. Họ cũng ở trong ý chính này .

test-shell-default-variables.sh

#!/bin/bash

# test-shell-default-variables.sh

# Usage examples (you might want to `sudo apt install zsh ksh`):
#
#  ./test-shell-default-variables.sh dash bash
#  ./test-shell-default-variables.sh dash bash zsh ksh
#  ./test-shell-default-variables.sh dash bash zsh ksh | less -R

# `-R` in `less -R` to have less pass escape sequences directly to the terminal
# so we have colors.


# The "invoking with name `sh`" tests are commented because for every shell I
# tested (dash, bash, zsh and ksh), the output was the same as that of dash.

# The `test_expression` function also work with expansion changes. You can try
# lines like `test_expression '{BASH_SOURCE:-$0}'`.

echolor() {
    echo -e "\e[1;36m$@\e[0m"
}

tell_file() {
    echo File \`"$1"\` is:
    echo \`\`\`
    cat "$1"
    echo \`\`\`
    echo
}

SHELL_ARRAY=("$@")

test_command() {
    for shell in "${SHELL_ARRAY[@]}"
    do
        prepare "$shell"
        cmd="$(eval echo $1)"
        # echo "cmd: $cmd"
        printf '%-4s: ' "$shell"
        { env -i $cmd 2>&1 1>&3 | sed 's/^/[err]/'; } 3>&1
        teardown
    done
    echo
}

prepare () {
    shell="$1"
    PATH="$PWD/$shell/sh:$PATH"
}

teardown() {
    PATH="${PATH#*:}"
}


###
### prepare
###
for shell in "${SHELL_ARRAY[@]}"
do
    mkdir "$shell"
    ln -sT "/bin/$shell" "$shell/sh"
done

echo > printer.sh
echo '. ./printer.sh' > sourcer.sh
rm linked.sh &>/dev/null; ln -sT "printer.sh" "linked.sh"

tell_file sourcer.sh

###
### run
###
test_expression() {
    local expr="$1"

    # prepare
    echo "echo $expr" > printer.sh
    tell_file printer.sh

    # run
    cmd='$shell ./printer.sh'
    echolor "\`$cmd\` (simple invocation) ($expr):"
    test_command "$cmd"

    # cmd='sh ./printer.sh'
    # echolor "\`$cmd\` (when executable name is \`sh\`) ($expr):"
    # test_command "$cmd"

    cmd='$shell ./sourcer.sh'
    echolor "\`$cmd\` (via sourcing) ($expr):"
    test_command "$cmd"

    # cmd='sh ./sourcer.sh'
    # echolor "\`$cmd\` (via sourcing, when name is \`sh\`) ($expr):"
    # test_command "$cmd"

    cmd='$shell ./linked.sh'
    echolor "\`$cmd\` (via symlink) ($expr):"
    test_command "$cmd"

    # cmd='sh ./linked.sh'
    # echolor "\`$cmd\` (via symlink, when name is \`sh\`) ($expr):"
    # test_command "$cmd"

    echolor "------------------------------------------"
    echo
}

test_expression '$BASH_SOURCE'
test_expression '$0'
test_expression '$(/bin/true x y; true a b c; echo $_)' # Rq: true is a builtin
test_expression '$_'

###
### teardown
###
for shell in "${SHELL_ARRAY[@]}"
do
    rm "$shell/sh"
    rm -d "$shell"
done

rm sourcer.sh
rm linked.sh
rm printer.sh

Đầu ra của ./test-shell-default-variables.sh {da,ba,z,k}sh

File `sourcer.sh` is:
```
. ./printer.sh
```

File `printer.sh` is:
```
echo $BASH_SOURCE
```

`$shell ./printer.sh` (simple invocation) ($BASH_SOURCE):
dash: 
bash: ./printer.sh
zsh : 
ksh : 

`$shell ./sourcer.sh` (via sourcing) ($BASH_SOURCE):
dash: 
bash: ./printer.sh
zsh : 
ksh : 

`$shell ./linked.sh` (via symlink) ($BASH_SOURCE):
dash: 
bash: ./linked.sh
zsh : 
ksh : 

------------------------------------------

File `printer.sh` is:
```
echo $0
```

`$shell ./printer.sh` (simple invocation) ($0):
dash: ./printer.sh
bash: ./printer.sh
zsh : ./printer.sh
ksh : ./printer.sh

`$shell ./sourcer.sh` (via sourcing) ($0):
dash: ./sourcer.sh
bash: ./sourcer.sh
zsh : ./printer.sh
ksh : ./sourcer.sh

`$shell ./linked.sh` (via symlink) ($0):
dash: ./linked.sh
bash: ./linked.sh
zsh : ./linked.sh
ksh : ./linked.sh

------------------------------------------

File `printer.sh` is:
```
echo $(/bin/true x y; true a b c; echo $_)
```

`$shell ./printer.sh` (simple invocation) ($(/bin/true x y; true a b c; echo $_)):
dash: 
bash: c
zsh : c
ksh : 

`$shell ./sourcer.sh` (via sourcing) ($(/bin/true x y; true a b c; echo $_)):
dash: 
bash: c
zsh : c
ksh : 

`$shell ./linked.sh` (via symlink) ($(/bin/true x y; true a b c; echo $_)):
dash: 
bash: c
zsh : c
ksh : 

------------------------------------------

File `printer.sh` is:
```
echo $_
```

`$shell ./printer.sh` (simple invocation) ($_):
dash: 
bash: bash
zsh : 
ksh : 

`$shell ./sourcer.sh` (via sourcing) ($_):
dash: 
bash: bash
zsh : ./printer.sh
ksh : 

`$shell ./linked.sh` (via symlink) ($_):
dash: 
bash: bash
zsh : 
ksh : 

------------------------------------------

Chúng ta đã học được gì?

$BASH_SOURCE

  • $BASH_SOURCE hoạt động trong bash và chỉ trong bash.
  • Sự khác biệt duy nhất $0là khi tệp hiện tại được lấy từ một tệp khác. Trong trường hợp đó, $BASH_PROFILEchứa tên của tệp có nguồn gốc, thay vì tên của tệp chua.

$0

  • Trong zsh, $0có cùng giá trị như $BASH_SOURCEtrong bash.

$_

  • $_ không bị ảnh hưởng bởi dấu gạch ngang và ksh.
  • Trong bash và zsh, $_phân rã đến đối số cuối cùng của cuộc gọi cuối cùng.
  • bash khởi tạo $_thành "bash".
  • lá zsh $_không bị ảnh hưởng. (khi tìm nguồn cung ứng, đó chỉ là kết quả của quy tắc "đối số cuối cùng").

Liên kết

  • Khi một tập lệnh được gọi thông qua một liên kết tượng trưng, ​​không có biến nào chứa bất kỳ tham chiếu nào đến đích của liên kết, chỉ có tên của nó.

ksh

  • Về những thử nghiệm đó, ksh hành xử như dấu gạch ngang.

sh

  • Khi bash hoặc zsh được gọi thông qua một liên kết tượng trưng có tên sh, liên quan đến các thử nghiệm đó, nó hoạt động giống như dấu gạch ngang.

0

Đối với bash shell, tôi thấy câu trả lời của @Dennis Williamson hữu ích nhất, nhưng nó không hoạt động trong trường hợp sudo. Cái này không

if ( [[ $_ != $0 ]] && [[ $_ != $SHELL ]] ); then
    echo "I'm being sourced!"
    exit 1
fi

0

Để làm cho tập lệnh của bạn tương thích cả bash- và zsh thay vì sử dụng các câu lệnh if bạn chỉ có thể viết ${BASH_SOURCE[0]:-${(%):-%x}}. Giá trị kết quả sẽ được lấy từ BASH_SOURCE[0]khi được xác định và ${(%):-%x}}khi BASH_SOURCE [0] không được xác định.


0

tl; dr script=$(readlink -e -- "${BASH_SOURCE}") (đối với bash rõ ràng)


$BASH_SOURCE trường hợp kiểm tra

tập tin đã cho /tmp/source1.sh

echo '$BASH_SOURCE '"(${BASH_SOURCE})"
echo 'readlink -e $BASH_SOURCE'\
     "($(readlink -e -- "${BASH_SOURCE}"))"

source các tập tin trong cách cư xử khác nhau

source từ /tmp

$> cd /tmp

$> source source1.sh
$BASH_SOURCE (source1.sh)
readlink -e $BASH_SOURCE (/tmp/source1.sh)

$> source ./source1.sh
$BASH_SOURCE (./source1.sh)
readlink -e $BASH_SOURCE (/tmp/source1.sh)

$> source /tmp/source1.sh
$BASH_SOURCE (/tmp/source1.sh)
readlink -e $BASH_SOURCE (/tmp/source1.sh)

source từ /

cd /
$> source /tmp/source1.sh
$0 (bash)
$BASH_SOURCE (/tmp/source1.sh)
readlink -e $BASH_SOURCE (/tmp/source1.sh)

sourcetừ những con đường tương đối khác nhau /tmp/a/var

$> cd /tmp/a

$> source ../source1.sh
$BASH_SOURCE (../source1.sh)
readlink -e $BASH_SOURCE (/tmp/source1.sh)

$> cd /var

$> source ../tmp/source1.sh
$BASH_SOURCE (../tmp/source1.sh)
readlink -e $BASH_SOURCE (/tmp/source1.sh)

về $0

trong mọi trường hợp, nếu tập lệnh có lệnh được thêm vào

echo '$0 '"(${0})"

sau đó sourcekịch bản luôn được in

$0 (bash)

tuy nhiên , nếu tập lệnh được chạy , vd

$> bash /tmp/source1.sh

sau đó $0sẽ là giá trị chuỗi /tmp/source1.sh.

$0 (/tmp/source1.sh)
$BASH_SOURCE (/tmp/source1.sh)
readlink -e $BASH_SOURCE (/tmp/source1.sh)

0

câu trả lời này mô tả cách thức lsofvà một chút ma thuật grep là điều duy nhất dường như có cơ hội làm việc cho các tệp có nguồn gốc lồng nhau trong tcsh:

/usr/sbin/lsof +p $$ | grep -oE /.\*source_me.tcsh

-2
wdir="$PWD"; [ "$PWD" = "/" ] && wdir=""
case "$0" in
  /*) scriptdir="${0%/*}";;
  *) scriptdir="$wdir/${0#./}"; scriptdir="${scriptdir%/*}";;
esac
echo "$scriptdir"

Có thể điều này sẽ không hoạt động với các liên kết tượng trưng hoặc các tệp có nguồn gốc nhưng hoạt động cho các tệp bình thường. Lấy làm tham khảo fro. @kenorb Không có dirname, readlink, BASH_SOURCE.


1
Nó đã được giải thích trong câu hỏi $0giúp bạn có thông tin về tập lệnh hiện đang chạy chứ không phải tập lệnh có nguồn gốc.
Scott

-3

Trên thực tế, "dirname $ 0" sẽ đưa bạn đường dẫn đến tập lệnh, nhưng bạn phải diễn giải nó một chút:

$ cat bash0
#!/bin/bash
echo \$0=$0
dirname $0
$ bash0    # "." appears in PATH right now.
$0=./bash0
.
$ ./bash0
$0=./bash0
.
$ $PWD/bash0
$0=/home/00/bediger/src/ksh/bash0
/home/00/bediger/src/ksh
$ $PWD/../ksh/bash0
$0=/home/00/bediger/src/ksh/../ksh/bash0
/home/00/bediger/src/ksh/../ksh
$ ../ksh/bash0
$0=../ksh/bash0
../ksh

Bạn phải chuẩn bị để xử lý "." như tên thư mục trong một số trường hợp phổ biến. Tôi sẽ thử nghiệm một chút, vì tôi nhớ tên dir được tích hợp sẵn để ksh làm mọi thứ hơi khác khi "." xuất hiện trong ĐƯỜNG.


4
Đây là một tập lệnh có nguồn gốc, không phải là một tập lệnh được thực thi. $0chỉ đơn giản chứa "bash" cho trình bao tương tác và đó là tất cả các tập lệnh có nguồn gốc nhìn thấy.
Cascabel
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.