我试图通过在Mac OS X上使用login/注销挂钩脚本来自动挂载一个EncFS卷。这些脚本以root用户身份运行,并在用户login或注销时自动运行用户定义的挂钩。 主脚本位于/usr/local/sbin ,被称为loginhook和logouthook 。 这是login脚本:
#!/bin/bash LOCAL_HOOK="/Users/$1/.loginhook" if [ -e "$LOCAL_HOOK" ] then su - $1 -c "bash $LOCAL_HOOK" fi
该脚本注册后执行login:
sudo defaults write com.apple.loginwindow LoginHook /usr/local/sbin/loginhook
用户定义的.loginhook :
ENCFS=/path/to/encfs PWD=$(security find-generic-password -ga EncFS 2>&1 >/dev/null | cut -d'"' -f2) echo $PWD | $ENCFS -S $HOME/.encrypted/Vault $HOME/Documents/Vault
security命令的redirect是必要的,因为正常的输出到标准输出,但密码到标准错误,看起来像password: "mypass" 。
如果我从我的用户帐户执行.localhook脚本工作正常,但是如果脚本从“父”脚本(作为根运行)通过使用su我得到一个空白的密码。
使用bash -xdebugging表明,所有东西都按照它应该运行,但env命令显示,尽pipe在脚本中使用su -login,但环境与我login时不一样。 我怀疑这是问题所在,但是我很难理解它是什么。
我在这里做错了什么?
编辑:基于Gordon Davisson信息的LaunchAgent解决scheme。
encfsd.sh :
#!/bin/bash ENCFS="/path/to/encfs" ENCDIR="$HOME/.encrypted/Vault" DECDIR="$HOME/Documents/Vault" function cleanup { # Kill sleep command ($! is PID of last command launched in background) kill $! umount "$DECDIR" exit } trap cleanup 1 2 3 6 15 security find-generic-password -ga EncFS 2>&1 >/dev/null | cut -d'"' -f2 | "$ENCFS" -S "$ENCDIR" "$DECDIR" # Wait for exit while true; do # Sleeping ignores normal signals so start it in a subprocess and wait for it sleep 3600 & wait done
~/Library/LaunchAgents/localhost.encfsd.plist :
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>KeepAlive</key> <false/> <key>Label</key> <string>localhost.encfsd</string> <key>LimitLoadToSessionType</key> <string>Background</string> <key>Program</key> <string>/Users/asdf/bin/encfsd.sh</string> <key>RunAtLoad</key> <true/> </dict> </plist>
login和logouthook脚本在用户会话之前和之后(而不是在会话之内)运行。 我怀疑,因为你的login挂钩在用户会话开始之前运行,所以用户的钥匙串还没有被解锁,所以你不能从它恢复密码。 LaunchAgent可能会更好地为此工作…