![su-에서 환경 변수를 보존하는 방법은 무엇입니까?](https://linux55.com/image/104351/su-%EC%97%90%EC%84%9C%20%ED%99%98%EA%B2%BD%20%EB%B3%80%EC%88%98%EB%A5%BC%20%EB%B3%B4%EC%A1%B4%ED%95%98%EB%8A%94%20%EB%B0%A9%EB%B2%95%EC%9D%80%20%EB%AC%B4%EC%97%87%EC%9E%85%EB%8B%88%EA%B9%8C%3F.png)
원격 시스템에 SSH를 사용할 때 LC_ALL="en_US.UTF-8"
(ssh_config를 통해 sendEnv
) 내보냅니다. 이 변수는 su - user123
쉘에 로그인 하면 재설정됩니다. LC_xxx
원격 시스템에서 다른 사용자로 로그인 셸을 실행할 때 이 변수(및 기타 변수)를 보존하는 방법이 있습니까?
쉘이나 대상 사용자의 항목을 실행한 후 수동으로 변수를 내보낼 수 있다는 것을 알고 있지만 ~/.bashrc
가능하다면 전송된 원래 값을 유지하려고 합니다 ssh
. 감사해요.
편집하다:사용자 환경의 특정 부분을 초기화해야 하기 때문에 su -
. 난 그냥 저장하고 싶어LC_xxx
답변1
su
나는 and의 구현(그리고 결국 coreutils에서는 제거되었지만 GNU의 구현)에 환경을 보존할 수 있는 옵션이 있다는 것을 발견했습니다 .util-linux
shadow-utils
coreutils
su
-m, -p, --preserve-environment
Preserve the current environment, except for:
...
다른 시스템에는 -m
(BSD와 같은) -p
둘 다 있거나 없을 수도 있습니다. Busybox 에는 및 가 su
있습니다 . 장난감 상자 (안드로이드) 예 .-m
-p
su
-p
이런 방식으로 대상 사용자의 셸 초기화 파일은 로그인 셸처럼 실행되지만 모든 LC_xxx
변수를 테스트할 수 있지만 이미 유효한 값이 포함된 경우 초기화되지 않습니다.
편집하다:/etc/profile.d/ssh_lc_vars.sh
내보낸 LC_xxx 변수를 처리하는 스크립트를 추가하여 이 기능을 시스템 전체에 적용 할 수 있습니다 . 또한 초기화되지 않은 환경 변수를 사용하여 몇 가지 추가 작업을 수행해야 했지만 작동하지 않았습니다 su -ml userxxx
. 전체 스크립트를 포함할 수 없었기 때문에 다음은 더 많은 예입니다. 누군가 개선해 주시면 더 좋을 것 같습니다.
...
# clean up client-side variable for junk
lc_sanitize()
{
arg="$1"
# first, strip underscores
clean="${arg//_/}"
# next, replace spaces with underscores
clean="${clean// /_}"
# now, clean out anything that's not alphanumeric, underscore, hypen or dot
ret="${clean//[^a-zA-Z0-9_\.-]/}"
# return santized value to caller
echo "$ret"
}
# LC_MY_LANG comes from an ssh client environment. If empty,
# this isn't a remote ssh user, but set it locally so this user
# can connect elsewhere where this script runs
if [ -z "$LC_MY_LANG" ]; then
# force an LC_xxx setting for the environment
LC_MY_LANG="en-US.utf-8"
else
# otherwise, use the LC_xxxx variable from the ssh environment
# 2017-01-30 - when using "su --preserve-environment userxxx --login" be sure to fixup needed variables
# shorthand: su -ml user111
export USER=`whoami`
export LOGNAME=${USER}
export HOME=$( getent passwd "$USER" | cut -d: -f6 )
cd ${HOME}
# sanitize variable which was set client-side and log it
u_sanitized=$(lc_sanitize "$LC_MY_LANG")
echo "Notice: LC_MY_LANG sanitized to $u_sanitized from $SSH_CLIENT as user $USER" | logger -p auth.info
fi
# mark variable read-only so user cannot change it then export it
readonly LC_MY_LANG
# set terminal to LC_MY_LANG
export LC_LANG=${LC_MY_LANG}
export LC_MY_LANG
...
답변2
-
su에 대한 인수를 건너뜁니다 .
-, -l, --login
Provide an environment similar to what the user would expect had
the user logged in directly.
답변3
다음은 나에게 효과적이었습니다. 이는 환경 변수를 설정하는 명령을 실행하는 데 사용되는 추가 셸을 호출하는 것과 같습니다.
# LC_ALL is set in parent shell
> export LC_ALL=C
> env | grep LC_ALL
LC_ALL=C
# Verify that since we use `su -` the LC_ALL is not preserved
> su - user123 -c '/bin/bash'
user123@026aedc05a97:~$ env | grep LC_ALL
user123@026aedc05a97:~$ exit
# Pass the variable to the extra shell explicitly
> su - user123 -c 'LC_ALL='$LC_ALL' /bin/bash'
# The variable is now set
user123@026aedc05a97:~$ env | grep LC_ALL
LC_ALL=C
user123@026aedc05a97:~$