从 ksh 脚本确定当前 shellsu - user
是否为登录 shell ( ) 的最佳方法是什么su user
?
我正在玩弄:
user=$(/usr/xpg4/bin/id -un)
login=$(grep $HOME /etc/passwd | cut -d: -f1 | head -1)
if [ "$login" == "$user" ]; then
...
fi
或者使用$MAIL
基于注释的变量苏手册页仅su -
设置邮件:
user=$(/usr/xpg4/bin/id -un)
login=${MAIL##*/}
if [ "$login" == "$user" ]; then
...
fi
但似乎两者都不是绝对无懈可击的。有没有最佳实践方法?
答案1
case "$0" in
-*) echo "I'm a login shell";;
esac
答案2
没有一种最佳实践。任何基于识别变量的方法都是不可靠的,甚至在流程层次上走动也需要进行推断,因为苏执行登录无需分叉,也不会留下任何关于其论点的痕迹。
更好的选择是直接测试您需要的设置。通常,我在寻找登录 shell 时感兴趣的是配置文件是否被读取。因此,如果您可以自由修改配置文件,请设置一个指示变量:
echo "export parsed_profile=true" >> ~/.profile
然后直接检查。另一个选择是验证您是否拥有 $HOME:
if /bin/test \! -O "$HOME"; then
echo HOME is not set or set incorrectly.
fi
或者直接从脚本内部获取您的配置文件。
答案3
你的问题是比我提出的更简单;你可能只是在问如何判断用户以 root 身份登录或使用 su 切换到它们在这种情况下,我给出的答案的组合是合适的。
通常,登录 shell 与非登录 shell 的区别在于是否运行了各种脚本。许多用户启动非登录 shell 的原因是它是某个程序的子 shell,或者(如您所说)因为他们用它su
来切换用户。那些用户将$LOGNAME
不等于$USER
当然,除非他们切换回来。要检测这些用户,请考虑以下 perl 脚本:
open(P,"ps -ef|");while(<P>){m#^(\S+)\s+(\d+)\s+(\d+)#;$u{$2}=$1;$t{$2}=$3;}
$p=$$;while($t{$p}){$g{$u{$p}}=1;$p=$t{$p};}delete$g{root};$g{$u{$$}}=1;
print keys(%g),"\n";
如果您想限制使用,su -
可以使用:
open(P,"ps -ef|");while(<P>){m#^(\S+)\s+(\d+)\s+(\d+).*su - #;$u{$2}=$1;$t{$2}=$3;}
$p=$$;while($t{$p}){$g{$u{$p}}=1;$p=$t{$p};}delete$g{root};$g{$u{$$}}=1;
print keys(%g),"\n";
如果你想真的参见登录 shell,请注意,登录 shell 以带有argv[0]
前导破折号的 set 开头,因此您可以使用:
open(P,"ps -eo user,pid,ppid,comm|");while(<P>){m#^(\S+)\s+(\d+)\s+(\d+) -#;
$u{$2}=$1;$t{$2}=$3;}
$p=$$;while($t{$p}){$g{$u{$p}}=1;$p=$t{$p};}delete$g{root};$g{$u{$$}}=1;
print keys(%g),"\n";
但你会错过有人逃跑的情况ksh --login
。
答案4
这不是绝对的,但大多数情况下应该有效
如果[$HOME ==“/root”]…