2009-03-25 8 views
2

000の権限を持つBash関数を実行できるのは完全に厳密なものではありませんが、ほとんどの場合です。私のコードは次のとおりです。私は、現在の権限で入力し、Firtslyなぜ000権限でBash関数を実行できますか?

-r-------- 1 UnixBasics hello_file 

を::

$ . ./hello_file;hello 

微調整は、に400件のパーミッションを変更することです

#!/bin/bash 
function hello { 
echo Hello! } 

ハローファイルが権限を持っています000 bashスクリプトスクリプトを実行する直前:

$ chmod 000 hello_file 
$ . ./hello_file;hello            [1] 
-bash: ./hello_file: Permission denied 
Hello! 

エラーが1つありますが、関数の実行は停止しません。私は理解できない。 hello関数の設定を解除しました: "unset hello"。エラーが表示されます:

-bash: ./hello_file: Permission denied 
-bash: hello: command not found 

なぜ私は最初にそれらを取得できませんでしたか?それはキャッシュやバッファなどと何か関係がありますか?なぜ000の権限でBashスクリプトを実行できますか?

+0

最初の行は "#!/ bin/bash"です。 –

+0

@Andrewありがとうございます。 –

+0

私の文章を批判的に解釈したAndrew Medicoに感謝します。その結果、小さな討論のように見える私の執筆において、いくつかの厄介な誤りが見つかりました。うまくいけば、すべてが今正しいです。 –

答えて

11

あなたは、スクリプトを実行していないされて、あなたはそれ(を含む)ソーシングです。スクリプトのソースを取得するには、読み取り権限のみが必要です。

ところで、機能は単に存在し、彼らは許可を持っていません。ファイルがソースとなり、関数が定義されたら、必要なだけ実行することができます。


更新:

なぜ私が初めてでそれらを取得していませんか?それはキャッシュやバッファなどと何か関係がありますか?

はい、Paxの回答と同じように、以前はファイルの以前のソースからhelloが定義されていた可能性があります。 sourcing( "。"組み込みコマンド)とは混同されるかもしれません。 Sourcingはファイルを読み込み、現在のシェルですべてのコマンドを実行した後、プロンプトに戻ります。したがって、ファイルを一度実行すると、その関数は現在のシェルインスタンスで定義され、そのシェルセッションを終了する(またはそれらの設定を解除する)まで、そこにとどまります。

なぜ000の権限[1]でBashスクリプトを実行できますか?

できません。エラーが発生することに注意してください。出力を引用する:

$ . ./hello_file;hello            [1] 
-bash: ./hello_file: Permission denied 
Hello! 

1つのコマンドラインで2つのコマンドを実行しました。 「許可が拒否されました」と表示されています。 「こんにちは!」出力は以前のファイルのソースからのものです。設定を解除して同じコマンドラインをもう一度試してみると、あなた自身がそれを証明しただけです。

キャッシュを呼び出すことはできません。シェルの仕組みです。あなたは別のファイルをソースします。その定義はすべて現在のシェルセッションに含まれ、そこにとどまります。実際にスクリプト(ソーシングしていない)を実行している場合、現在のセッションに残渣がないはずです。

$ chmod +x hello_file 
$ ./hello_file   # note: executed, not sourced 
$ hello 
-bash: hello: command not found 
+0

それは正しくありません。 perm = 100の場合でも、 "permission denied"を与えてもスクリプトのソースを許可しません。ソーシングは、サブシェルではなく、現在のシェルのコンテキストで実行されます。自分で試してみることをお勧めします。 – paxdiablo

+0

Pax:私は約100または000のアクセス権について主張していません。私は、exec権限がソースコード( "。"組み込みコマンド)に影響しないと主張しています。なぜdownvote? – Juliano

+0

downvoteはあなたが間違っているからです - 試して見てください。 perm = 000または100の場合、ソーシングは機能しません。 – paxdiablo

5

もっともらしい説明は、hello_fileが保護され、その機能が既に作成される前に実行されたということです。それであなたはあなたのスクリプトを保護しました(あなたはコマンドで100と言っていますが、あなたのテキストでは000と言います)。

したがって、スクリプトは実行されません。しかし、hello()は前回の実行からまだ定義されています。

新しいシェルを開くか、unset helloを実行してみてください。

+0

あなたの答えはあなたが推測しているように聞こえる。私は与えられた最初の答えが正しいと思う - 彼は読みやすいファイルを調達するだけです。シェル関数には権限がありません。 –

+0

それは推測ではありません、私はそれをテストしました。また、アクセス権は関数を作成する*ファイル*にあります。*関数ではありません。 – paxdiablo

+0

私は訂正しました。申し訳ありません。 –

2

モードを100に変更する前にスクリプトを実行しましたか(「.hell_file」を実行しましたか?)その場合、 "hello"関数は単純にbashにロードされます。その後、読み取り不可能なファイルのソースを取得しようとしても、それは変更されません。正しくテストするには、フレッシュシェルを起動してください。

+0

私はいくつかの訂正を行い、質問に詳細を追加しました。明らかに、彼らは質問に答えるために不可欠です。 –

2

プログラムを実行するには(bashスクリプトであれ、バイナリ実行ファイルであれ)、実行権限が必要です。コマンドを入力すると、最初の単語(たとえば、./fooなど)が実行するコマンドを指定します。これは別のプロセスとして起動されます。シェルスクリプトの場合は、#!行にリストされているシェルインタプリタの新しいコピーを実行し、そのインタプリタを使用してプログラムを実行します。

 
$ ls -l foo 
-rw-r--r-- 1 lambda lambda 23 Mar 25 20:02 foo 
$ chmod 744 foo # or chmod u+x foo 
$ ls -l foo 
-rwxr--r-- 1 lambda lambda 23 Mar 25 20:02 foo 
$ ./foo 
Hello 

あなたが.コマンドを使用すると、それが現在のシェルにファイルをソースすると言うシェル組み込みコマンドです。つまり、コマンドラインからコマンドを実行したかのように、ファイル内のコマンドを現在のファイルの中で実行します。ファイルを取得するには、読み取り権限のみが必要です。たとえば、サブプロセスに変数を設定しても、現在のシェルの値は変更されません。あなたが現在のシェルにbashスクリプトをソースならば、それは値を変更んが:

 
$ foo=bar 
$ cat setvariables 
#!/bin/sh 

foo=hello 
$ ./setvariables 
$ echo $foo 
bar 
$ . ./setvariables 
$ echo $foo 
hello 

を(あなたの例のように)シェル関数は、多くの変数のようなものですが、それは内のコマンドのように動作し現在のシェル。そのため、.を使用してhello_fileをソースすると、現在のシェルでその関数が定義され、定義した他のシェル関数と同様に実行できます。

権限については、アクセス許可を100に変更する前に(つまり、実行可能、読み取り不可、つまりファイルを読むことができなくてはならないため、ファイルにとっては無用です)何かをするために)、あなたはすでにあなたの現在のシェルにファイルを供給していました。これは、関数がすでに定義されていることを意味し、定義された後にそのファイルのパーミッションとは関係ありません。現在のシェルで関数が定義されると、そのファイルを削除することもできます。そのシェルがまだ開いている限り、関数はまだ定義されています。

編集:編集した質問からわかるように、機能を設定解除するとエラーが発生します。これは私の仮説が正しいこと、そして権限を変更する前にすでにファイルを入手していたことを強く示しています。私が説明したように、ファイルのソースと実行はまったく別の操作であり、一度ソースを取得するとそのアクセス権(または存在)はまったく問題になりません。関数はすでに実行中のシェルにロードされています。 unset helloを実行した後に元の実験を実行するとわかります。 chmod 000の場合は、読み取り権限を持たないようにして、関数を定義しないでください。

+1

ああ、なぜdownvote?私の説明に何か間違っているか役に立たないことはありますか? –

+0

これはほとんどの場合当てはまりますが、質問には無関係です(なぜ、明らかにモード100のファイルがソースになるのでしょうか)。特に、ファイルは実行可能である必要はなく、読み取り専用です。 –

+0

権限について明確にした段落を追加しました。彼はファイルをソースしたときには許可エラーがはっきりしていたので、以前の呼び出しの定義を持っていたに違いありません。私がソーシングとランニングの違いを説明したのは、その混乱がどこにあるのだろうと思うからです。 –

関連する問題