通过用户名获取主目录

puc*_*chu 113 linux bash

我想通过 echo 获取任何用户的主目录

echo ~puchuu
>> /home/puchuu
Run Code Online (Sandbox Code Playgroud)

但我不能使用变量

echo ~$USER
>> ~puchuu
echo `echo ~$USER`
>> ~puchuu
Run Code Online (Sandbox Code Playgroud)

cho*_*oba 115

您可以使用eval

eval echo ~$USER
Run Code Online (Sandbox Code Playgroud)

但请参阅下面Andrew的评论和glenn的回复。

  • 在 bash 中不需要 eval 只需要 `echo ~$username` 就可以了,但是在 sh 中,如果 eval 是一个变量,则需要它 (10认同)

gle*_*man 89

这可能对你有用:

homedir=$( getent passwd "$USER" | cut -d: -f6 )
Run Code Online (Sandbox Code Playgroud)

这也适用于不是您的用户。例如,

homedir=$( getent passwd "someotheruser" | cut -d: -f6 )
Run Code Online (Sandbox Code Playgroud)


gre*_*man 19

看来你就是那个用户——为什么不呢

echo $HOME
Run Code Online (Sandbox Code Playgroud)

?

  • 如果您处于 sudo 环境中并且没有传递 sudo -H 或 -i 标志,这将不起作用 - $HOME 仍将是前一个(sudo'ing)用户的主目录。 (5认同)

Bru*_*sky 12

有一个安全的方法可以做到这一点!

在 Linux/BSD/macOS/OSX 上无需 sudo 或 root

user=pi
user_home=$(bash -c "cd ~$(printf %q "$user") && pwd")
Run Code Online (Sandbox Code Playgroud)

注意:之所以安全,是因为 bash(甚至 4.4 之前的版本)有自己的printf功能,其中包括:

%q quote the argument in a way that can be reused as shell input

看:help printf

与其他答案如何响应代码注入进行比较

# "ls /" is not dangerous so you can try this on your machine
# But, it could just as easily be "sudo rm -rf /*"
$ user="root; ls /"
$ printf "%q" "$user"
root\;\ ls\ /

# This is what you get when you are PROTECTED from code injection
$ user_home=$(bash -c "cd ~$(printf "%q" "$user") && pwd"); echo $user_home
bash: line 0: cd: ~root; ls /: No such file or directory

# This is what you get when you ARE NOT PROTECTED from code injection
$ user_home=$(bash -c "cd ~$user && pwd"); echo $user_home
bin boot dev etc home lib lib64 media mnt ono opt proc root run sbin srv sys tmp usr var /root

$ user_home=$(eval "echo ~$user"); echo $user_home
/root bin boot dev etc home lib lib64 media mnt ono opt proc root run sbin srv sys tmp usr var
Run Code Online (Sandbox Code Playgroud)

在 Linux/BSD/macOS/OSX 上以 root 身份运行

如果你这样做是因为你正在运行某些东西,root那么你可以使用 sudo 的力量:

user=pi
user_home=$(sudo -u "$user" sh -c 'echo $HOME')
Run Code Online (Sandbox Code Playgroud)

在 Linux/BSD 上(但不是现代 macOS/OSX),无需 sudo 或 root

如果没有,您可以从 获取/etc/passwd。已经有很多使用evaland的例子getent,所以我将给出另一种选择:

user=pi
user_home=$(awk -v u="$user" -v FS=':' '$1==u {print $6}' /etc/passwd)
Run Code Online (Sandbox Code Playgroud)

如果我有一个包含许多其他 awk oneliners 的 bash 脚本并且不使用cut. 虽然许多人喜欢“编码高尔夫”以使用最少的字符来完成任务,但我更喜欢“工具高尔夫”,因为使用更少的工具可以使您的脚本具有更小的“兼容性足迹”。此外,您的同事或未来的自己也不需要阅读手册页来理解它。

  • 但是“$user”而不是“$USER” (2认同)