IT TIP

bash 스크립트에서 다른 사용자의 $ HOME 디렉토리를 얻는 방법은 무엇입니까?

itqueen 2020. 12. 28. 22:21
반응형

bash 스크립트에서 다른 사용자의 $ HOME 디렉토리를 얻는 방법은 무엇입니까?


bash 스크립트의 일부를 다른 사용자로 해당 사용자의 $HOME디렉터리 내에서 실행해야합니다 . 그러나이 변수를 결정하는 방법을 잘 모르겠습니다. 해당 사용자로 전환하고 전화를 걸어도 $HOME올바른 위치가 제공되지 않습니다.

# running script as root, but switching to a different user...
su - $different_user
echo $HOME
# returns /root/ but should be /home/myuser

최신 정보:

스크립트에서 사용자를 전환하려는 방식에 문제가있는 것 같습니다.

$different_user=deploy

# create user
useradd -m -s /bin/bash $different_user

echo "Current user: `whoami`"
# Current user: root

echo "Switching user to $different_user"
# Switching user to deploy

su - $different_user
echo "Current user: `whoami`"
# Current user: root
echo "Current user: `id`"
# Current user: uid=0(root) gid=0(root) groups=0(root)

sudo su $different_user
# Current user: root
# Current user: uid=0(root) gid=0(root) groups=0(root)

bash 스크립트에서 사용자를 전환하고 다른 사용자로 명령을 실행하는 올바른 방법은 무엇입니까?


업데이트 :이 질문의 제목에 따르면 사람들은 해당 사용자 가장필요없이 다른 사용자의 홈 디렉토리 찾을 수 있는 방법을 찾고있는 것 같습니다 .

이 경우 가장 간단한 해결책은 원하는 사용자 이름과 함께 물결표 확장eval 을 사용하는 것입니다 ( 물결 확장 이 작동하려면 사용자 이름이 인용되지 않은 리터럴 로 제공되어야하기 때문에 필요합니다 ).

eval echo "~$different_user"    # prints $different_user's home dir.

참고 : apply 사용에 관한 일반적인 주의 사항입니다eval . 이 경우 사용자가의 값을 제어하고 $different_user단순한 사용자 이름임을 알고 있다고 가정 합니다.

대조적으로,이 답변의 나머지를 다루는 가장하는 사용자 작업을 수행하는 사용자의 홈 디렉토리에 .


노트 :

  • 기본적으로 관리자 및 sudoers파일을 통해 승인 된 경우 다른 사용자는를 통해 다른 사용자를 가장 할 수 있습니다 sudo.
  • 다음은 기본 구성을 기반으로합니다. 구성을 sudo변경하면 다르게 동작 할 수 있습니다 man sudoers.

기본형 다른 사용자와 같이 명령어를 실행 :

sudo -H -u someUser someExe [arg1 ...]
  # Example:
sudo -H -u root env  # print the root user's environment

노트 :

  • 을 지정하지 않으면 -H가장 프로세스 (지정된 사용자의 컨텍스트에서 호출되는 프로세스)가에서 원래 사용자의 홈 디렉토리를 보고합니다 $HOME.
  • 가장 프로세스는 호출 프로세스와 동일한 작업 디렉터리를 갖습니다.
  • 프로세스 수행 사칭 없는 쉘 확장 에는 쉘이 (하지 않는 한 명의 도용 과정에 참여하지 않기 때문에, 인수로 전달 된 문자열 리터럴을 someExe바이 확장 - 쉘 될 일) 호출 쉘 - 이전에 명의 도용 과정에 통과에 - 분명히 여전히 발생할 수 있습니다 .

선택적으로, 당신은 가장하고 처리 할 수 있습니다 또는 A (n은 가장하는) 쉘을 통해 실행을 접두사로, someExe과하거나 -i 또는 -s - 지정되지는 someExe ...생성 대화 형 쉘을 :

  • -i에 대한 로그인 셸을 만듭니다. someUser이는 다음을 의미합니다.

    • someUser정의 된 경우사용자 별 셸 프로필이로드 됩니다.
    • $HOMEsomeUser의 홈 디렉토리를 가리 키 므로 필요하지 않습니다-H (여전히 지정할 수 있음).
    • 가장 셸의 작업 디렉터리는 someUser의 홈 디렉터리입니다.
  • -s 비 로그인 셸을 만듭니다.

    • 어떤 쉘 프로파일을 로드 (상호 작용에 대한 초기화 파일하지만 nonlogin의 껍질은, 예를 들어, ~/.bashrc)
    • 을 함께 지정하지 않는 한 -H가장 프로세스는에있는 원래 사용자의 홈 디렉토리를 보고합니다 $HOME.
    • 가장하는 셸은 호출 프로세스와 동일한 작업 디렉터리를 갖습니다.

명령 줄에서 전달 된 문자열 인수가 될 수 있음을 쉘 수단 사용 확장을 쉘 주제 - 아래의 플랫폼 별 차이 참조 - (아마도 호출 쉘에 의해 초기 확장 후) 명의 도용 쉘에 의해을; 다음 두 명령을 비교합니다 ( 호출하는 쉘에 의한 조기 확장을 방지하기 위해 작은 따옴표를 사용함 ).

  # Run root's shell profile, change to root's home dir.
sudo -u root -i eval 'echo $SHELL - $USER - $HOME - $PWD'
  # Don't run root's shell profile, use current working dir.
  # Note the required -H to define $HOME as root`s home dir.
sudo -u root -H -s eval 'echo $SHELL - $USER - $HOME - $PWD'

호출되는 은 "설정된 경우 SHELL 환경 변수 또는 passwd (5)에 지정된 쉘"(에 따라 man sudo)에 의해 결정됩니다. 참고로 그 -s는입니다 호출 문제가 가진 반면, 사용자의 환경 -i이하는 것이입니다 가장 된 사용자의.

셸 관련 동작 ( -i또는 사용 -s) 과 관련하여 플랫폼 차이있습니다 .

  • sudoLinux-s-i 에서는 / 다음 첫 번째 인수 실행 파일 또는 내장 이름 만 허용하는 반면 OSX는 전체 쉘 명령 줄을 전달할 수 있습니다. 예를 들어 OSX는 sudo -u root -s 'echo $SHELL - $USER - $HOME - $PWD'직접 허용 eval하지만 (필요 없음 ) Linux는 허용하지 않습니다 (현재 sudo 1.8.95p).

  • sudoLinux에서의 이전 버전은 쉘에 전달 된 인수에 쉘 확장을 적용하지 않습니다 . 예를 들어 sudo 1.8.3p1(예 : Ubuntu 12.04)에서는 sudo -u root -H -s echo '$HOME'루트 사용자의 컨텍스트에서 변수 참조를 확장하는 대신 문자열 리터럴 "$ HOME"을 에코합니다. 적어도 sudo 1.8.9p5(예 : Ubuntu 14.04)이 문제가 수정되었습니다. 따라서 이전 sudo버전 에서도 Linux에서 확장 하려면 전체 명령을 단일 인수로 eval; 예 : sudo -u root -H -s eval 'echo $HOME'. (OSX에서는 필요하지 않지만, 이것도 작동합니다.)

  • root사용자의 $SHELL변수는 포함 /bin/sh는 반면, OSX 10.9에 /bin/bash우분투 12.04에.

가장하는 프로세스는 쉘을 포함 여부, 환경이 호출하는 사용자와 명령을 반영, 다음 변수를 설정해야합니다 : SUDO_COMMAND, SUDO_USER, SUDO_UID=, SUDO_GID.

참조 man sudoman sudoers더 많은 미묘합니다.

영감을 얻기 위해 @DavidW와 @Andrew에게 모자를 씌우십시오.


BASH에서는 $HOME사용자의 로그인 ID 앞에 물결표 문자를 붙여 사용자의 디렉토리를 찾을 수 있습니다 . 예를 들면 :

$ echo ~bob

이것은 사용자 bob$HOME디렉토리를 표시합니다.

그러나 특정 사용자로 스크립트를 실행할 수 있기를 원한다고 말합니다. 그렇게하려면 sudo 를 설정해야합니다 . 이 명령을 사용하면 특정 사용자로 특정 명령을 실행할 수 있습니다. 예를 들어 foo사용자 로 실행하려면 다음을 수행하십시오 bob.

$ sudo -i -ubob -sfoo

이렇게하면 새 셸이 시작 -i되고는 사용자의 기본 환경 및 셸을 사용하여 로그인을 시뮬레이션합니다 (즉, foo명령이 bob's$ HOME` 디렉터리 에서 실행 됨을 의미합니다 ).

Sudo는 설정하기가 약간 복잡하며 shudders 파일 (보통 /etc/sudoers) 을 볼 수 있으려면 수퍼 유저 여야합니다 . 그러나이 파일에는 일반적으로 사용할 수있는 몇 가지 예제가 있습니다.

이 파일에서 명령을 실행할 수있는 사람, 사용자, 해당 사용자가 해당 명령을 실행하기 전에 암호를 입력해야하는지 여부를 지정하는 명령을 지정할 수 있습니다. 이것은 일반적으로 기본값입니다 (사용자가 Coke를받는 동안 방문한 사람이 아니라 사용자임을 증명하기 때문입니다.) 그러나 쉘 스크립트를 실행할 때 일반적으로이 기능을 비활성화하려고합니다.


사용자의 집 디렉토리를 찾는 간단한 방법을 찾는 사람들을위한 대체 답변을 위해 ...

su해킹을 엉망으로 만들 거나 환경 변수 bash를 찾기 위해 다른 을 시작하는 오버 헤드를 괴롭히는 대신 $HOME...

Bash를 통한 경량 단순 Homedir 쿼리

이를위한 명령이 있습니다. getent

getent passwd someuser | cut -f6 -d:

getent더 많은 것을 할 수 있습니다 ... man page를 보세요. passwdnsswitch에 데이터베이스에서 사용자의 항목 반환 /etc/passwd형식을. 콜론 :으로 분할 하여 필드를 구문 분석하십시오.

대부분의 Linux 시스템 (또는 GNU Lib C (RHEL : glibc-common, Deb :) 을 사용하는 모든 시스템에 설치해야합니다 . libc-bin)


이 경우에 -u대한 옵션 이 필요합니다 sudo. 로부터 man페이지 :

The -u (user) option causes sudo to run the specified command as a user other than root.

실제로 실행할 필요가 없다면 ~<user>. 에서와 같이 내 홈 디렉토리로 이동하려면 cd ~chooban.


따라서 다음을 원합니다.

  1. 실행 배시 스크립트의 일부를 다른 사용자로
  2. 해당 사용자의 $ HOME 디렉토리로 변경

이 답변 에서 영감을 얻은 스크립트는 다음과 같습니다.

#!/usr/bin/env bash

different_user=deploy

useradd -m -s /bin/bash "$different_user"

echo "Current user: $(whoami)"
echo "Current directory: $(pwd)"
echo

echo "Switching user to $different_user"
sudo -u "$different_user" -i /bin/bash - <<-'EOF'
    echo "Current user: $(id)"
    echo "Current directory: $(pwd)"
EOF
echo

echo "Switched back to $(whoami)"

different_user_home="$(eval echo ~"$different_user")"
echo "$different_user home directory: $different_user_home"

실행하면 다음이 표시됩니다.

Current user: root
Current directory: /root

Switching user to deploy
Current user: uid=1003(deploy) gid=1003(deploy) groups=1003(deploy)
Current directory: /home/deploy

Switched back to root
deploy home directory: /home/deploy

이것은 Linux에서 작동합니다. 다른 * 닉스에서 어떻게 작동하는지 확실하지 않습니다.

  getent passwd "${OTHER_USER}"|cut -d\: -f 6

나는 또한 이것을 찾고 있었지만 단순히 경로를 얻기 위해 사용자를 가장하고 싶지 않았습니다!

user_path=$(grep $username /etc/passwd|cut -f6 -d":");

이제 스크립트 $user_path에서 대부분의 경우 참조 할 수 있습니다./home/username

Assumes: You have previously set $username with the value of the intended users username. Source: http://www.unix.com/shell-programming-and-scripting/171782-cut-fields-etc-passwd-file-into-variables.html


Quick and dirty, and store it in a variable:

USER=somebody
USER_HOME="$(echo -n $(bash -c "cd ~${USER} && pwd"))"

I was struggling with this question because I was looking for a way to do this in a bash script for OS X, hence /etc/passwd was out of the question, and my script was meant to be executed as root, therefore making the solutions invoking eval or bash -c dangerous as they allowed code injection into the variable specifying the username.

Here is what I found. It's simple and doesn't put a variable inside a subshell. However it does require the script to be ran by root as it sudos into the specified user account.

Presuming that $SOMEUSER contains a valid username:

echo "$(sudo -H -u "$SOMEUSER" -s -- "cd ~ && pwd")"

I hope this helps somebody!


If the user doesn't exist, getent will return an error.

Here's a small shell function that doesn't ignore the exit code of getent:

get_home() {
  local result; result="$(getent passwd "$1")" || return
  echo $result | cut -d : -f 6
}

Here's a usage example:

da_home="$(get_home missing_user)" || {
  echo 'User does NOT exist!'; exit 1
}

# Now do something with $da_home
echo "Home directory is: '$da_home'"

The title of this question is How to get $HOME directory of different user in bash script? and that is what people are coming here from Google to find out.

If you are doing this because you are running something as root then you can use the power of sudo:

user=pi
user_home=$(sudo -u $user sh -c 'echo $HOME')

If not, the you can get it from /etc/passwd. There are already lots of examples of using eval and getent, so I'll give another option:

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

I would really only use that one if I had a bash script with lots of other awk oneliners and no uses of cut. While many people like to "code golf" to use the fewest characters to accomplish a task, I favor "tool golf" because using fewer tools gives your script a smaller "compatibility footprint". Also, it's less man pages for your coworker or future-self to have to read to make sense of it.


The output of getent passwd username can be parsed with a Bash regular expression

OTHER_HOME="$(
  [[ "$(
    getent \
    passwd \
    "${OTHER_USER}"
  )" =~ ([^:]*:){5}([^:]+) ]] \
  && echo "${BASH_REMATCH[2]}"
)"

ReferenceURL : https://stackoverflow.com/questions/20504662/how-to-get-home-directory-of-different-user-in-bash-script

반응형