2017-11-15 7 views
0

このディレクトリ構造を皮切り:このファイルのソースは2回目とは異なる動作をするのはなぜですか?

$ tree 
. 
├── 1 
│   └── 2 
│    └── foo.jar 
└── a 
    └── b 
     └── c 
      └── setAlias 

目標はsetAliasの内容を思い付くことですので、私はファイルをソースすることができ、そしてそれはjava -jar /absolute/path/to/foo.jar

ここで私はですが実行され、エイリアスを作成します。これまで持っている:

FOO="java -jar $(realpath $(dirname $_)/../../../1/2/foo.jar)" 
echo "Setting Alias:" 
echo " foo -> $FOO" 
alias foo='$FOO' 

直接、独自のIソースsetAlias場合は、すべてが正常に動作します。しかし、私は、ルートディレクトリからそれを設定した場合、私はabsouluteパスが解決される前に、それを2回実行する必要があります。

$ source a/b/c/setAlias 
realpath: ./../../../1/2/foo.jar: No such file or directory 
Setting Alias: 
    foo -> java -jar 

$ source a/b/c/setAlias 
Setting Alias: 
    foo -> java -jar /home/MatrixManAtYrService/1/2/foo.jar 

私は./a/b/cからこれを行う場合はパスが最初の試行で解決されます。

ここで何が起こっているかなぜrealpathは2つのファイルを見つけようとしますか?

+1

bashのマンページには、非常に長い時間、次の行が含まれています。「ほぼすべての目的のために、エイリアスはシェル関数に取って代わられています。 IOW、エイリアスを使用しない*。ただ停止する。 –

+0

私は心にそれを取ることを確認します。なぜ私は代わりに関数をエクスポートするとは思わなかったのか分かりません。 – MatrixManAtYrService

答えて

1

これは非常に奇妙なことですが、簡単に説明できます。ここでman bash下の特殊パラメータ

$_からの抜粋だ[..]拡張後に、前のコマンドの最後の引数に展開されます。 [...]つまり

を、それが最後に実行されたコマンドの最後の引数を参照する:あなたのケースでは

$ echo foo bar baz 
foo bar baz 

$ echo $_ 
baz 

、あなたは、あなたのポストには示されていないいくつかの任意のコマンドを実行します。二回source続く:あなたはその最後の引数として$_の必要値を使用するコマンドが先行したときに言い換えれば

$ true foobar   # $_ now becomes "foobar"  
$ source a/b/c/setAlias # fails because $_ is "foobar", sets $_ to a/b/c/setAlias 
$ source a/b/c/setAlias # works because $_ is now "a/b/c/setAlias" 

、あなたのsourceのみ動作します。これは何でもかまいません:

$ wc -l a/b/c/setAlias # also sets $_ to a/b/c/setAlias 
4 
$ source a/b/c/setAlias # Works, because $_ is set to the expected value 

おそらくget the current script's pathにしたかったですか?

+0

私は '$ _'が私に必要なパスを構築する' source'の引数を与えることを私の頭の中に持っていました。通常、前のコマンドは 'cd a/b/c'だったので、ほとんどの場合動作するように思えました。あなたがリンクしている投稿は、私が何をしたのかを示す方法を示しています。ありがとう。 – MatrixManAtYrService

関連する問題