Le tilde, '~' est-il considéré comme un chemin relatif?

33

J'essaie d'extraire la partie différente du programme d'installation de la bibliothèque Nvidia cuda. J'utilise la commande suivante:

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

Et je reçois le message suivant:

ERROR: extract: path must be absolute.

Et quand je tape la commande avec l’adresse littérale de ma maison, cela fonctionne parfaitement.

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

Je suis confus ne devrait pas ~ être le même de / home / likewise-open / XXX / nom d'utilisateur?

Testé:

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

et ça marche, mais je ne sais pas pourquoi il ne permet pas ~

    
posée Regan 27.08.2014 - 15:19
la source

4 réponses

45

Bash développe uniquement un ~ s'il s'agit du début d'un mot. Vous pouvez voir cela entre les commandes suivantes:

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

[email protected]:~$ echo -extract ~/test
-extract /home/oli/test

Bash recherche les caractères ~ autonomes et ~/ pour cette substitution. Aucune autre combinaison ou version citée ne fonctionnera.

$HOME fonctionne car les substitutions de variables sont plus robustes (le $ est un caractère spécial alors que ~ l'est beaucoup moins):

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

Bien que nous parlions de ~ , il existe en réalité deux autres utilisations de substitution:

  • ~+ le répertoire de travail en cours (lu depuis $PWD )
  • ~- le répertoire de travail précédent (lu depuis $OLDPWD )

Comme avec plain ~ , ceux-ci peuvent avoir des chemins supplémentaires à la fin, et encore une fois, ceux-ci doivent être le préfixe d'un mot ou Bash les ignorera.

Vous pouvez en savoir plus à ce sujet dans man bash | less -p ' Tilde'

    
réponse donnée Oli 27.08.2014 - 15:35
la source
19

Il suffit de le réparer

Cette commande affiche un message d'erreur "ERREUR: extrait: le chemin doit être absolu":

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

L'erreur n'est pas utile - le programme était déjà trop confus.
Vous savez déjà que l'erreur provient du ~ , car elle fonctionne plutôt avec $HOME .

Le problème: ~ seulement est remplacé au début d'un mot.

Par exemple, cela fonctionne avec le tilde:

echo -extract ~/Downloads

Si vous avez besoin de la syntaxe d’option avec = , utiliser $ HOME au lieu de ~ est la solution la plus propre;

echo -extract=$HOME/Downloads

La pratique

Ce que vous devez savoir:

Il y a des cas particuliers où ~ get est développé lorsqu'il n'est pas au début d'un mot: dans le cadre d'une affectation de variable, directement après = . Ce qui est déroutant ici, bien sûr.

L'autre cas particulier important à utiliser avec des variables comme PATH. Dans les affectations de variables, ~ est également développé après : , comme après le premier = .

$ 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

La signification du tilde

Dans un shell, ~ , le tilde, n’est pas vraiment un chemin. Il est seulement remplacé par un chemin, $HOME , à certains moments.

C'est quelque chose comme un raccourci, ou une abréviation, fourni par le shell.
Il ne peut pas être utilisé comme un chemin en général, le shell le "étend" à un chemin uniquement dans des endroits très particuliers.
Et même s’il est étendu, il peut s’agir de quelque chose d’autre que le répertoire de base.

  • Il est uniquement développé au début d'un mot ou dans une affectation de variable après : ou =
  • Il est seulement développé s'il ne contient pas entre guillemets
  • Il est seulement étendu à $HOME s'il y a pas d'autres caractères dans le mot avant /

Le problème dans la ligne de commande

Selon cela, le problème dans votre commande est que le tilde dans

-extract=~/Downloads/nvidia_installers

n'est pas développé, car ce n'est pas l'un des cas répertoriés. C'est tout.

La solution pourrait être de faire du tilde le premier caractère non coté d'un mot, sans autre caractère avant le prochain / - c'est exactement ce que vous obtenez lorsque vous utilisez une option avec un espace avant l'argument option:

-extract ~/Downloads/nvidia_installers

Une autre solution consisterait à utiliser $HOME à la place. Dans un script, c'est généralement le meilleur choix.

-extract=$HOME/Downloads/nvidia_installers

Le message d'erreur

Mais comment le message d'erreur de "ERROR: extract: path must be absolute." ?
rentrez dans tout ça?

Nous savons que le tilde n’a pas été développé. Cela signifie que le programme a obtenu le texte d'argument incluant ~ , mais sans le /home/auser comme chemin. Ce chemin est ~/Downloads/nvidia_installers - mais maintenant il n'y a plus de shell, donc le tilde n'a pas de signification particulière. C'est juste un nom de répertoire normal. Et comme tout autre chemin de la forme foo/bar/baz , c'est un chemin relatif

Autres utilisations

S'il y a des caractères après ~ , comme dans ~alice - avec toutes les autres règles ci-dessus - et si un utilisateur se nomme alice , il est étendu au répertoire de base de alice , dites home/alice .
De plus, si vous êtes bob , ~ deviendrait /home/bob et ~bob deviendrait le même.

La variante ~+ est étendue au répertoire en cours, $PWD

Pour faire référence au répertoire précédent, où vous étiez avant le dernier cd , vous pouvez utiliser ~- , qui est étendu à $OLDPWD .

Si vous utilisez pushd et popd , au lieu de cd , vous savez déjà que la pile de répertoires est accessible comme ~-2 .

Détails

Tous les cas où ~ est étendu à un chemin sont gérés par le shell . Pour les autres programmes, ~ est juste un caractère de nom de fichier normal.

Pour la définition exacte dans le shell, voici la section correspondante de man bash
Notez que remplacer ~ par $HOME n'est qu'un cas particulier de nombreux cas: "Si ce nom de connexion est la chaîne NULL, le tilde est remplacé par la valeur du paramètre shell 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.
    
réponse donnée Volker Siegel 27.08.2014 - 17:08
la source
3

~ n'est pas un chemin en soi. C'est un caractère qui reçoit un traitement spécial du shell où ~ ou ~/ signifie "remplacer par le chemin du répertoire personnel de l'utilisateur actuel". ~username signifie "remplacer par le chemin du répertoire personnel du nom d'utilisateur".

Comme ce n’est pas un chemin, il est uniquement reconnu à certains endroits de la commande (en tant que premier caractère d’un nouveau jeton fractionné dans l’espace).

Une fois développé, il a été remplacé par un chemin absolu.

L'utilisation de $HOME works car HOME n'est qu'une variable définie par le shell et suit les règles de shell normales pour le remplacement des variables (cela se produit avant que l'entrée soit divisée en espaces et exécutée).

    
réponse donnée Daenyth 27.08.2014 - 15:54
la source
1

Vous avez raison le ~ / Téléchargements est identique à / home / nom d'utilisateur / Téléchargements.

Certains installateurs et extracteurs sont très exigeants en ce qui concerne la mise en place des choses. Je pense que cela pourrait être parce qu'il enregistre les chemins de fichiers, et les journaux n'accepteront pas ~ dans un chemin accepté.

Je me suis juste habitué à taper / home / username à la place. :)

    
réponse donnée Dan Johansen 27.08.2014 - 15:24
la source

Lire d'autres questions sur les étiquettes