チルダ、「〜」は相対パスと見なされますか?


35

Nvidia cuda libraryインストーラーの異なる部分を抽出しようとしています。私は次のコマンドを使用しています:

mkdir ~/Downloads/nvidia_installers
./cuda_6.5.14_linux_64.run -extract=~/Downloads/nvidia_installers

そして、次のメッセージが表示されます。

ERROR: extract: path must be absolute.

また、自宅の住所をそのまま使用してコマンドを入力すると、完全に機能します。

./cuda_6.5.14_linux_64.run -extract=/home/likewise-open/XXX/username/Downloads/nvidia_installers

〜/ home / likewise-open / XXX / usernameと同じであってはいけません。

テスト済み:

./cuda_6.5.14_linux_64.run -extract=$HOME/Downloads/nvidia_installers

そしてそれは動作しますが、なぜそれが許可されないのか分かりません ~


2
関連:「A 『チルダプレフィックスは、』最初の引用符で囲まれていないが、前のすべての文字に続いて、単語の先頭に引用符で囲まれていない<チルダ>文字で構成され、」
Braiam

回答:


47

Bashは、単語の始まりである場合にのみ〜を展開します。これは、次のコマンド間で確認できます。

$ echo -extract=~/test
-extract=~/test

oli@bert:~$ echo -extract ~/test
-extract /home/oli/test

Bashは、スタンドアロンの~文字と~/この置換を探します。他の組み合わせまたは引用バージョンは機能しません。

$HOME変数置換がより堅牢であるため機能します($これ~は特殊文字ですが、非常に少ないためです)。

$ echo Thisisastring${HOME}awrawr
Thisisastring/home/oliawrawr

について話している間~、実際には別の置換の使用法がいくつかあります:

  • ~+現在の作業ディレクトリ(から読み取り$PWD
  • ~-前の作業ディレクトリ(から読み取り$OLDPWD

plainの~場合と同様に、これらには最後に追加のパスを付けることができます。また、これらは単語のプレフィックスである必要があります。そうしないと、Bashはそれらを無視します。

詳細については、こちらをご覧ください man bash | less -p ' Tilde'


2
それはそれは注目に値するzsh (というかに設定することができます)を展開~した後=、あまりにも。他の便利な改良点の中で、bashを上回っています。
1月Hudec 14

@JanHudecいいえ-もっと複雑です。後に拡張することではありません=。変数の割り当ての右側の先頭で展開することです。よく見ると、ケースが少し混乱します。私の答えをご覧ください。そして、これzshと違いはありませんbash。'zsh'の説明は少しわかりにくいですinfo --subnodes zsh | less +/'14.7.4 Notes'(zshのマニュアルページがありません)
Volker Siegel 14

1
@VolkerSiegel:zsh非常に構成可能です。私のzshのecho -extract=~/test結果では-extract=/home/user/testMAGIC_EQUAL_SUBSTオプションによって有効になります。ちなみに、私はすべてのzshのマニュアルページをうまく持っています。
Jan Hudec 14

@JanHudec zsh構成可能であることは間違いありません-その他の改善。MAGIC_EQUAL_SUBST(14.7.4でカバー)がデフォルトで設定されておらず、ほとんど使用されないと予想していました。今では、一般的に有効にした方が明らかにより関連性があります。私は良い形で私の例のセクションを取得した後、それは...素晴らしい追加になるだろう
フォルカー・シーゲル

@JanHudec zshのmanページに関しては、しばらくの間Ubuntuパッケージから欠落していました。ヒントのおかげで、それが修正されたことを知りませんでした。バグを見ると、それはutopic向けに修正されていますが、信頼できるものではありません。(ランチパッド:すべてのzshマンページとインラインヘルプファイルが欠落しており、AU:zsh manが欠落しています...
Volker Siegel 14

19

修正するだけ

このコマンドは、「エラー:抽出:パスは絶対パスでなければなりません」というエラーメッセージを表示します。

./cuda_6.5.14_linux_64.run -extract=~/Downloads/nvidia_installers

エラーは役に立たない-プログラムは既に混乱しすぎていた。
エラーはからのもの~であることが既にわかっています$HOME

問題:~単語の先頭でのみ置き換えられます。

たとえば、これはチルダで機能します。

echo -extract ~/Downloads

でオプション構文が必要な場合は、最もクリーンなソリューションである=代わりに$ HOMEを使用し~ます。

echo -extract=$HOME/Downloads

練習

知っておくべきこと:

~単語の先頭にないときにgetが展開される特殊なケースがあります=。変数の割り当ての一部として、の直後にあります。もちろん、これは紛らわしいです。

もう1つの重要な特別なケースは、PATHなどの変数で使用することです。変数の割り当てで~は、の後:に展開され=ます。

$ dir=~ sh -c 'echo D2: $dir'
D2: /home/user
$ sh -c 'echo D2: $dir' dir=~
D2: 
$ echo Dir: $dir
Dir:
$ dir=~; sh -c 'echo D2: $dir'
D2: 
$ echo Dir: $dir
Dir: /home/user
$ sh -c 'echo D2: $dir'; d3=~
D2: 
$ echo d3: $d3
d3: /home/user

チルダの意味

シェルで~は、チルダは実際にはパスではありません。それは、パスによってのみ置き換えられる場合があります$HOME

これは、シェルが提供する短縮形または略語のようなものです。
一般にパスのように使用することはできません。シェルは、非常に特別な場所でのみパスに「拡張」します。
そして、たとえそれが拡張されたとしても、それはホームディレクトリ以外のものになりえます。

  • それだけで展開されている単語の先頭に、または後に変数の割り当て:または=
  • 引用符内にない場合にのみ展開されます
  • 単語の前にさらに文字$HOMEない場合にのみ展開されます/

コマンドラインの問題

これによると、コマンドの問題は、チルダが

-extract=~/Downloads/nvidia_installers

リストされているケースの1つではないため、展開されません。それで全部です。

解決策は、チルダを単語の最初の引用されていない文字にし、次の文字の前に他の文字/を入れないことです。

-extract ~/Downloads/nvidia_installers

別の解決策は、$HOME代わりに使用することです。スクリプトでは、通常、それがより良い選択です。

-extract=$HOME/Downloads/nvidia_installers

エラーメッセージ

しかし、エラーメッセージは
"ERROR: extract: path must be absolute."どうですか?
これらすべてに適合しますか?

チルダが展開されなかったことを知っています。つまり、プログラムはを含む引数テキストを取得しました~/home/auser、パスとしてはありません。そのパスは~/Downloads/nvidia_installers-しかし、今はシェルがないため、チルダには特別な意味はありません。通常のディレクトリ名です。そして、フォームの他のすべてのパスのようにfoo/bar/baz、それは相対パスです

その他の用途

上記の他のすべてのルールが適用さ~れるように~alice-の後に文字があり、ユーザー名がある場合は、代わりaliceにのホームディレクトリに展開されaliceますhome/alice
また、あなたがしている場合bob~に拡大する/home/bob、と~bob同じに拡大します。

バリアント~+は現在のディレクトリに展開され、$PWD

最後の前にいた前のディレクトリを参照するにはcd、を使用~-$OLDPWDます。これはに展開されます。

pushdとのpopd代わりにand を使用すると、cdディレクトリスタックに~-2

詳細

~パスに展開されるすべてのケースは、シェルによって処理されます。他のプログラムの場合~は、単なる通常のファイル名文字です。

以下のために正確な定義殻の内側、ここでの関連セクションで 置き換える方法注では、多くの例一つだけの特別なケースでは:このログイン名がNULL文字列の場合は」、チルダはシェルパラメータHOMEの値に置き換えられます。 」man bash
~$HOME

Tilde Expansion
    If a word begins with an unquoted tilde character (`~'), all of the charac‐
    ters  preceding the first unquoted slash (or all characters, if there is no
    unquoted slash) are considered a tilde-prefix.  If none of  the  characters
    in  the tilde-prefix are quoted, the characters in the tilde-prefix follow‐
    ing the tilde are treated as a possible login name.  If this login name  is
    the  null string, the tilde is replaced with the value of the shell parame‐
    ter HOME.  If HOME is unset, the home directory of the user  executing  the
    shell is substituted instead.  Otherwise, the tilde-prefix is replaced with
    the home directory associated with the specified login name.

    If the tilde-prefix is a `~+', the value of the shell variable PWD replaces
    the  tilde-prefix.   If  the tilde-prefix is a `~-', the value of the shell
    variable OLDPWD, if it is set, is substituted.  If the characters following
    the tilde in the tilde-prefix consist of a number N, optionally prefixed by
    a `+' or a `-', the tilde-prefix is replaced with the corresponding element
    from  the  directory  stack,  as  it would be displayed by the dirs builtin
    invoked with the tilde-prefix as an argument.  If the characters  following
    the  tilde in the tilde-prefix consist of a number without a leading `+' or
    `-', `+' is assumed.

    If the login name is invalid, or the tilde expansion  fails,  the  word  is
    unchanged.

    Each variable assignment is checked for unquoted tilde-prefixes immediately
    following a : or the first =.  In these cases, tilde expansion is also per‐
    formed.   Consequently, one may use filenames with tildes in assignments to
    PATH, MAILPATH, and CDPATH, and the shell assigns the expanded value.

3

~パス自体ではありません。これは、シェルから特別扱いを受けるの文字だ~または~/「現在のユーザのホームディレクトリのパスに置き換え」を意味します。~username「ユーザー名のホームディレクトリパスで置き換える」という意味です。

これはパスではないため、コマンドの特定の場所でのみ認識されます(新しいスペース分割トークンの最初の文字として)。

展開すると、絶対パスに置き換えられます。

$HOMEHOMEがシェルによって設定された変数であり、変数置換の通常のシェル規則に従うため、使用することは機能します(入力がスペースで分割され実行される前に発生します)。


1

あなたは正しいです。〜/ Downloadsは/ home / username / Downloadsと同じです。

一部のインストーラーとエクストラクターは、物を置く必要がある場所について非常にうるさいです。ファイルパスを記録し、ログが受け入れられたパスで〜を受け入れないためだと思います。

代わりに/ home / usernameを入力することに慣れました。:)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.