Comment obtenir le répertoire de base de l'utilisateur hôte dans WSL Bash

6

Je veux obtenir le répertoire personnel de l'utilisateur "hôte" Windows à partir de bash, donc ma variable d'environnement théorique (ou programme)

echo $WINHOME

produirait quelque chose comme

/mnt/c/Users/dualed

Cela serait-il possible?

Lorsque je le recherche, je ne trouve que les résultats pour le contraire (recherche du chemin d’utilisateur de LXSS auprès de l’hôte)

J'ai une idée de repli de l'extraction $PATH, car il existe des chemins prévisibles comme ceux qui contiennent AppData, mais je préférerais garder les choses simples, si possible.

à double
la source
Non, juste les variables habituelles Linux comme HOME, PWD, USER, mais ils se réfèrent tous à l'utilisateur de Linux, pas à l'utilisateur Windows « hôte ».
jumelé
Apparemment un duplicata de stackoverflow.com/questions/44971719/…
dualed

Réponses:

4

Vous pouvez lancer cmd.exedepuis bash pour obtenir les variables d'environnement de l'hôte. Dans ce qui suit, win_userprofilea votre réponse, et les autres variables sont pour la complétude.

win_userprofile="$(cmd.exe /c "<nul set /p=%UserProfile%" 2>/dev/null)"

win_userprofile_drive="${win_userprofile%%:*}:"
userprofile_mount="$(findmnt --noheadings --first-only --output TARGET "$win_userprofile_drive")"

win_userprofile_dir="${win_userprofile#*:}"

userprofile="${userprofile_mount}${win_userprofile_dir//\\//}"

Sources: Craig Loewen chez Microsoft et Michael Hoffman .

harrymc
la source
Eh bien, pour être précis $win_userprofilecontient le chemin des fenêtres, $userprofiledétient la réponse à ma question, mais oui, c'est à peu près ce que je cherchais. Cependant, je préférerais que la traduction du chemin Windows vers le chemin Unix soit moins
complexe
Je viens de trouver github.com/Microsoft/WSL/issues/1834#issuecomment-346443730 "La version 17046 de Windows Insider contient une nouvelle fonctionnalité 'wslpath' qui prend en charge les traductions de chemin"
Du
Excellente réponse. J'avais eu beaucoup d'éléments ensemble, mais j'avais deux problèmes. (1) Parce que je pensais en avoir besoin, je testais dans un sudo -sshell root ( ) et cmd.exeje n'étais pas sur mon chemin. Je cherchais donc un moyen de le trouver. dans le shell de connexion, cela n'est pas nécessaire. (2) Bien que cmd.exe /c echo %userprofile%donne le chemin dans Windows, je luttais avec des sedfiltres complexes sur mountou dfpour mapper le (DriveLetter):chemin vers le chemin Linux; findmntest une solution très soignée. Merci beaucoup: j'ai beaucoup appris.
AFH
2

Depuis que j'ai écrit cette question, l'outil wslpatha été ajouté à WSL / LXSS. Cet outil peut convertir les chemins de fenêtres en point de montage correct (?) Sur le sous-système Linux. La solution la plus simple serait donc la suivante:

export WINHOME=$(wslpath $(cmd.exe /C "echo %USERPROFILE%"))
# echo $WINHOME prints something like /mnt/c/Users/dualed

De plus, il semble maintenant possible de mettre en cascade des environnements. C’est donc aussi une option:

export WINHOME=$(cmd.exe /C "cd /D %USERPROFILE% && bash.exe -c pwd")

PS: L' wslpathoutil semble extrêmement alpha:

man wslpath
# No manual entry for wslpath
# See 'man 7 undocumented' for help when manual pages are not available.
wslpath /?
# wslpath: /?: Invalid argument
wslpath -?
# wslpath: unrecognized option: ?
# wslpath: Invalid argument
wslpath --help
# wslpath: unrecognized option: -
# wslpath: Invalid argument
wslpath
# wslpath: Invalid argument

juste un petit avertissement.


Mise à jour, espérons-le, utile: J'utilise actuellement un petit assistant pour récupérer les variables d'environnement Windows

#!/bin/bash
# 'winenv'
cmd.exe /C "echo %$*%" | tr -d '\r'

Et en l'utilisant comme:

WINHOME=$(wslpath "$(winenv USERPROFILE)")
à double
la source
wslpathn'est pas un outil. C'est juste un lien symbolique (c'est-à-dire un lien symbolique ln -s) d'un /initfichier dans un rootfsdossier.
Biswapriyo
Oui, il semble que /initl'exécutable se trouve derrière wslpath, mais il agit différemment lorsque wslpathvous l'appelez, alors j'appellerai toujours l'outil wslpathet non /init. Il a également été annoncé wslpathpar les développeurs: github.com/Microsoft/WSL/issues/1834#issuecomment- 346443730
jumelé
1

C’est ma réponse de référence , si la question ne devait pas donner lieu à une réponse pour le moment, ou ne serait pas claire. Il fait ce que j'ai écrit dans la question que je voulais éviter - deviner le répertoire de base de l'utilisateur en cherchant des champs contenant AppData(et un peu plus) dans$PATH

#!/bin/bash
IFS=':' read -a fields <<<"$PATH"

for field in "${fields[@]}"; do
        if [[ $field =~ ^(/mnt/.*)/AppData/Local/.* ]]; then
                echo ${BASH_REMATCH[1]}
                exit
        fi
done

Bien sûr, il faut qu’il y ait au moins un chemin dans %APPDATA%Windows et (ce qui est plus problématique à mon avis) qu’il n’y ait pas de chemin AppData défini avec d’autres noms d’utilisateur, par exemple dans une portée globale et enfin que le répertoire de base soit réellement monté dans. /mnt.

Exemple de sortie:

$ winhome
/mnt/c/Users/dualed
à double
la source
1

beaucoup de bonnes infos ici! Merci. j'avais besoin d'un tweak supplémentaire ..

quand j'utilise l' cmd.exeastuce dans mon .bash_aliasesfichier, j'obtiens des erreurs dues aux caractères de nouvelle ligne indésirables de CMD echo, qui wslpathpassent à travers:

$ echo $(cmd.exe /C "echo %USERPROFILE%") | cat -A
C:\Users\myself^M$
               ^-- no good, wslpath turns into /mnt/c/Users/myself^M$

CMD echo ne semble pas avoir l' -noption de bash echo , donc empruntant à un article de StackOverflow ( batch Windows: echo sans nouvelle ligne ), j'ai ajouté un pseudo-chomp pour les supprimer:

$ echo $(cmd.exe /C "echo | set /p _=%USERPROFILE%") | cat -A
C:\Users\myself
               ^-- all gone!

et maintenant mon alias est heureux:

export WINHOME="$(wslpath $(cmd.exe /C "echo | set /p _=%USERPROFILE%"))"
Ellemenno
la source
Oui, bon point, je me souviens de cela, puis évidemment oublié de mettre à jour ma réponse - même si j'ai supprimé le \rWSL, je pense avoir utilisé quelque chose comme | tr -d '\r'(voir comme \rn'est pas valide dans les chemins de Windows de toute façon), mais c'est juste moi d'être plus à l'aise dans Linux
doublé le
0

En supposant que vous connaissiez votre identifiant Windows, vous pouvez le mettre dans votre fichier .profile: export WINHOME = $ (wslpath C: / Users / dualed)

rhmccullough
la source
Je ne veux pas coder en dur le chemin, sinon je pourrais simplement définir directement le chemin Unix. Aussi wslpathne fonctionne que dans les constructions d'initiés pour l'instant
jumelé
D'ACCORD. ajoutez ces deux lignes à .profile:
rhmccullough
apps = $ (echo $ PATH | sed 's: / \ n / g' | grep WindowsApps); export WINHOME = $ {WINHOME %% / AppData *}
rhmccullough
oops: exportez WINHOME = $ {apps %% / AppData *}
rhmccullough
La procédure ci-dessus échouera s'il y a plusieurs WindowsApps dans $ PATH. Il est préférable de créer un script shell d’une ligne contenant: echo "$ PATH" | sed 's /: / \ n / g' | grep WindowsApps | sed 's, / AppData. * ,, | trier -u
rhmccullough
0

As-tu essayé

env | grep '\\ utilisateurs \\ <votre nom d'utilisateur> '
?

En Cygwin, je reçois

HOMEPATH = \ Utilisateurs \ <mon-nom d'utilisateur> 
USERPROFILE = C: \ Utilisateurs \ <mon-nom d'utilisateur> 
APPDATA = C: \ Utilisateurs \ <mon-nom d'utilisateur> \ AppData \ Roaming
LOCALAPPDATA = C: \ Utilisateurs \ <mon-nom d'utilisateur> \ AppData \ Local
Bien sûr, Cygwin n’est pas le même que WSL, mais il se peut qu’une réponse simple vous attende depuis le début.

Scott
la source
Les utilisateurs sur WSL sont complètement indépendants des utilisateurs Windows. Lors de la configuration d'un environnement WSL, vous créez un utilisateur WSL uniquement. Une personne peut choisir n’importe quel nom valide dans la distribution choisie, ce qui n’est donc pas utile dans mon cas car je cherchais une solution générique.
jumelé