替换用户 mid-Bash-script 并继续 运行 命令 (Mac OSX)
Substitute user mid-Bash-script & continue running commands (Mac OSX)
我正在构建两个脚本,它们结合起来将完全卸载 Mac OS X 上的程序 (Microsoft Lync)。我需要能够从具有 root 访问权限的帐户进行交换(这帐户最初执行第一个脚本)给当前登录的用户。
这是必要的,因为第二个脚本不仅需要由登录用户执行,还需要来自所述用户的 shell。在此示例中,这两个脚本是名称 Uninstall1.sh
和 Uninstall2.sh
。
Uninstall1.sh(root用户执行):
#!/bin/bash
#commands ran by root user
function rootCMDs () {
pkill Lync
rm -rf /Applications/Microsoft\ Lync.app
killall cfprefsd
swapUser
}
function swapUser () {
currentUser=$(who | grep console | grep -v _mbsetupuser | grep -v root | awk '{print }' | head -n 1)
cp /<directory>/Uninstall2.sh${currentUser}
su -l ${currentUser} -c "<directory>/{currentUser}/testScript.sh";
<directory>
实际上在脚本中声明了,但为了保护隐私,我将其排除。
在上面的脚本中,我 运行 一些基本命令作为 root 用户将应用程序删除到垃圾箱,并终止 cfprefsd 以防止必须重新启动机器。然后我调用 swapUser
函数,该函数动态识别当前登录的用户帐户并将其分配给变量 currentUser
(在我们的环境中的这种情况下,假设只有一个用户登录是安全的一次电脑)。我不确定我是否还需要 cp directory/Uninstall2.sh
部分,但这是为了解决不同的问题。
主要问题是让脚本正确处理 su
命令。我使用 -l
标志来模拟用户登录,这是必要的,因为这不仅替代了登录的用户帐户,而且它作为所述用户启动了一个新的 shell。我需要使用 -l
因为 OS X 不允许从管理员帐户修改另一个用户的钥匙串(有问题的管理员帐户具有 root 访问权限,但不是也不会切换到 root)。 -c
意在执行复制的脚本,如下:
Uninstall2.sh(需要本地登录用户执行):
#!/bin/bash
function rmFiles () {
# rm -rf commands
# rm -rf commands
certHandler1
}
function certHandler1 () {
myCert=($(security dump-keychain | grep <string> | grep alis | sed -e 's/"alis"<blob>="//' | sed -e 's/"//'))
cLen=${#myCert[@]} # Count the amount of items in the array; there are usually duplicates
for ((i = 0;
i < ${cLen};
i++));
do security delete-certificate -c ${myCert[$i]};
done
certHandler2
}
function certHandler2 () {
# Derive the name of, and delete Keychain items related to Microsoft Lync.
myAccount=$(security dump-keychain | grep KeyContainer | grep acct | sed -e 's/"acct"<blob>="//' | sed -e 's/"//')
security delete-generic-password -a ${myAccount}
lyncPW=$(security dump-keychain | grep Microsoft\ Lync | sed -e 's/<blob>="//' | awk '{print , }' | sed -e 's/"//')
security delete-generic-password -l "${lyncPW}"
}
rmFiles
在上面的脚本中,rmFiles
通过从用户的 ~/Library
目录中删除一些文件和目录来启动脚本。这没有问题,假设来自 Uninstall1.sh
的 su
使用本地用户的 shell 正确执行第二个脚本。
然后我使用 security dump-keychain
转储本地用户的 shell,找到一个特定的证书,然后将所有结果分配给 cLen
数组(因为用户的钥匙串中可能有重复项) .然后删除数组中的每个项目,之后动态找到并删除更多钥匙串项目。
我一直在发现的是,第一个脚本将正确地 su
到它找到的登录用户,此时第二个脚本根本不会 运行 。或者,第二个脚本是 运行 作为 root 用户,因此没有正确删除它应该 su
到的已登录用户的钥匙串项目。
抱歉这么长 post,感谢阅读,我期待对这种情况有所了解!
修订
我设法找到一种方法来实现我在单个 bash 脚本中尝试做的所有事情,而不是两个。为此,我让主脚本在 /tmp 中创建另一个 bash 脚本,然后以本地用户身份执行该脚本。我将在下面提供它以帮助可能需要此功能的其他人:
关于如何在 bash 脚本中创建另一个 bash 脚本的代码归功于以下来源:
http://tldp.org/LDP/abs/html/here-docs.html - 示例 19.8
#!/bin/bash
# Declare the desired directory and file name of the script to be created. I chose /tmp because I want this file to be removed upon next start-up.
OUTFILE=/tmp/fileName.sh
(
cat <<'EOF'
#!/bin/bash
# Remove user-local Microsoft Lync files and/or directories
function rmFiles () {
rm -rf ~/Library/Caches/com.microsoft.Lync
rm -f ~/Library/Preferences/com.microsoft.Lync.plist
rm -rf ~/Library/Preferences/ByHost/MicrosoftLync*
rm -rf ~/Library/Logs/Microsoft-Lync*
rm -rf ~/Documents/Microsoft\ User\ Data/Microsoft\ Lync\ Data
rm -rf ~/Documents/Microsoft\ User\ Data/Microsoft\ Lync\ History
rm -f ~/Library/Keychains/OC_KeyContainer*
certHandler1
}
# Need to build in a loop that determines the count of the output to determine whether or not we need to build an array or use a simple variable.
# Some people have more than one 'PRIVATE_STRING' certificate items in their keychain - this will loop through and delete each one. This may or may not be necessary for other applications of this script.
function certHandler1 () {
# Replace 'PRIVATE_STRING' with whatever you're searching for in Keychain
myCert=($(security dump-keychain | grep PRIVATE_STRING | grep alis | sed -e 's/"alis"<blob>="//' | sed -e 's/"//'))
cLen=${#myCert[@]} # Count the amount of items in the array
for ((i = 0;
i < ${cLen};
i++));
do security delete-certificate -c ${myCert[$i]};
done
certHandler2
}
function certHandler2 () {
# Derive the name of, then delete Keychain items related to Microsoft Lync.
myAccount=$(security dump-keychain | grep KeyContainer | grep acct | sed -e 's/"acct"<blob>="//' | sed -e 's/"//')
security delete-generic-password -a ${myAccount}
lyncPW=$(security dump-keychain | grep Microsoft\ Lync | sed -e 's/<blob>="//' | awk '{print , }' | sed -e 's/"//')
security delete-generic-password -l "${lyncPW}"
}
rmFiles
exit 0
EOF
) > $OUTFILE
# -----------------------------------------------------------
# Commands to be ran as root
function rootCMDs () {
pkill Lync
rm -rf /Applications/Microsoft\ Lync.app
killall cfprefsd # killing cfprefsd mitigates the necessity to reboot the machine to clear cache.
chainScript
}
function chainScript () {
if [ -f "$OUTFILE" ]
then
# Make the file in /tmp executable. This is necessary for /tmp as a non-root user cannot access files in this directory.
chmod 755 $OUTFILE
# Dynamically identify the user currently logged in. This may need some tweaking if multiple User Accounts are logged into the same computer at once.
currentUser=$(who | grep console | grep -v _mbsetupuser | grep -v root | awk '{print }' | head -n 1);
su -l ${currentUser} -c "bash /tmp/UninstallLync2.sh"
else
echo "Problem in creating file: \"$OUTFILE\""
fi
}
# This method also works for generating
#+ C programs, Perl programs, Python programs, Makefiles,
#+ and the like.
# Commence the domino effect.
rootCMDs
exit 0
# -----------------------------------------------------------
干杯!
我正在构建两个脚本,它们结合起来将完全卸载 Mac OS X 上的程序 (Microsoft Lync)。我需要能够从具有 root 访问权限的帐户进行交换(这帐户最初执行第一个脚本)给当前登录的用户。
这是必要的,因为第二个脚本不仅需要由登录用户执行,还需要来自所述用户的 shell。在此示例中,这两个脚本是名称 Uninstall1.sh
和 Uninstall2.sh
。
Uninstall1.sh(root用户执行):
#!/bin/bash
#commands ran by root user
function rootCMDs () {
pkill Lync
rm -rf /Applications/Microsoft\ Lync.app
killall cfprefsd
swapUser
}
function swapUser () {
currentUser=$(who | grep console | grep -v _mbsetupuser | grep -v root | awk '{print }' | head -n 1)
cp /<directory>/Uninstall2.sh${currentUser}
su -l ${currentUser} -c "<directory>/{currentUser}/testScript.sh";
<directory>
实际上在脚本中声明了,但为了保护隐私,我将其排除。
在上面的脚本中,我 运行 一些基本命令作为 root 用户将应用程序删除到垃圾箱,并终止 cfprefsd 以防止必须重新启动机器。然后我调用 swapUser
函数,该函数动态识别当前登录的用户帐户并将其分配给变量 currentUser
(在我们的环境中的这种情况下,假设只有一个用户登录是安全的一次电脑)。我不确定我是否还需要 cp directory/Uninstall2.sh
部分,但这是为了解决不同的问题。
主要问题是让脚本正确处理 su
命令。我使用 -l
标志来模拟用户登录,这是必要的,因为这不仅替代了登录的用户帐户,而且它作为所述用户启动了一个新的 shell。我需要使用 -l
因为 OS X 不允许从管理员帐户修改另一个用户的钥匙串(有问题的管理员帐户具有 root 访问权限,但不是也不会切换到 root)。 -c
意在执行复制的脚本,如下:
Uninstall2.sh(需要本地登录用户执行):
#!/bin/bash
function rmFiles () {
# rm -rf commands
# rm -rf commands
certHandler1
}
function certHandler1 () {
myCert=($(security dump-keychain | grep <string> | grep alis | sed -e 's/"alis"<blob>="//' | sed -e 's/"//'))
cLen=${#myCert[@]} # Count the amount of items in the array; there are usually duplicates
for ((i = 0;
i < ${cLen};
i++));
do security delete-certificate -c ${myCert[$i]};
done
certHandler2
}
function certHandler2 () {
# Derive the name of, and delete Keychain items related to Microsoft Lync.
myAccount=$(security dump-keychain | grep KeyContainer | grep acct | sed -e 's/"acct"<blob>="//' | sed -e 's/"//')
security delete-generic-password -a ${myAccount}
lyncPW=$(security dump-keychain | grep Microsoft\ Lync | sed -e 's/<blob>="//' | awk '{print , }' | sed -e 's/"//')
security delete-generic-password -l "${lyncPW}"
}
rmFiles
在上面的脚本中,rmFiles
通过从用户的 ~/Library
目录中删除一些文件和目录来启动脚本。这没有问题,假设来自 Uninstall1.sh
的 su
使用本地用户的 shell 正确执行第二个脚本。
然后我使用 security dump-keychain
转储本地用户的 shell,找到一个特定的证书,然后将所有结果分配给 cLen
数组(因为用户的钥匙串中可能有重复项) .然后删除数组中的每个项目,之后动态找到并删除更多钥匙串项目。
我一直在发现的是,第一个脚本将正确地 su
到它找到的登录用户,此时第二个脚本根本不会 运行 。或者,第二个脚本是 运行 作为 root 用户,因此没有正确删除它应该 su
到的已登录用户的钥匙串项目。
抱歉这么长 post,感谢阅读,我期待对这种情况有所了解!
修订
我设法找到一种方法来实现我在单个 bash 脚本中尝试做的所有事情,而不是两个。为此,我让主脚本在 /tmp 中创建另一个 bash 脚本,然后以本地用户身份执行该脚本。我将在下面提供它以帮助可能需要此功能的其他人:
关于如何在 bash 脚本中创建另一个 bash 脚本的代码归功于以下来源:
http://tldp.org/LDP/abs/html/here-docs.html - 示例 19.8
#!/bin/bash
# Declare the desired directory and file name of the script to be created. I chose /tmp because I want this file to be removed upon next start-up.
OUTFILE=/tmp/fileName.sh
(
cat <<'EOF'
#!/bin/bash
# Remove user-local Microsoft Lync files and/or directories
function rmFiles () {
rm -rf ~/Library/Caches/com.microsoft.Lync
rm -f ~/Library/Preferences/com.microsoft.Lync.plist
rm -rf ~/Library/Preferences/ByHost/MicrosoftLync*
rm -rf ~/Library/Logs/Microsoft-Lync*
rm -rf ~/Documents/Microsoft\ User\ Data/Microsoft\ Lync\ Data
rm -rf ~/Documents/Microsoft\ User\ Data/Microsoft\ Lync\ History
rm -f ~/Library/Keychains/OC_KeyContainer*
certHandler1
}
# Need to build in a loop that determines the count of the output to determine whether or not we need to build an array or use a simple variable.
# Some people have more than one 'PRIVATE_STRING' certificate items in their keychain - this will loop through and delete each one. This may or may not be necessary for other applications of this script.
function certHandler1 () {
# Replace 'PRIVATE_STRING' with whatever you're searching for in Keychain
myCert=($(security dump-keychain | grep PRIVATE_STRING | grep alis | sed -e 's/"alis"<blob>="//' | sed -e 's/"//'))
cLen=${#myCert[@]} # Count the amount of items in the array
for ((i = 0;
i < ${cLen};
i++));
do security delete-certificate -c ${myCert[$i]};
done
certHandler2
}
function certHandler2 () {
# Derive the name of, then delete Keychain items related to Microsoft Lync.
myAccount=$(security dump-keychain | grep KeyContainer | grep acct | sed -e 's/"acct"<blob>="//' | sed -e 's/"//')
security delete-generic-password -a ${myAccount}
lyncPW=$(security dump-keychain | grep Microsoft\ Lync | sed -e 's/<blob>="//' | awk '{print , }' | sed -e 's/"//')
security delete-generic-password -l "${lyncPW}"
}
rmFiles
exit 0
EOF
) > $OUTFILE
# -----------------------------------------------------------
# Commands to be ran as root
function rootCMDs () {
pkill Lync
rm -rf /Applications/Microsoft\ Lync.app
killall cfprefsd # killing cfprefsd mitigates the necessity to reboot the machine to clear cache.
chainScript
}
function chainScript () {
if [ -f "$OUTFILE" ]
then
# Make the file in /tmp executable. This is necessary for /tmp as a non-root user cannot access files in this directory.
chmod 755 $OUTFILE
# Dynamically identify the user currently logged in. This may need some tweaking if multiple User Accounts are logged into the same computer at once.
currentUser=$(who | grep console | grep -v _mbsetupuser | grep -v root | awk '{print }' | head -n 1);
su -l ${currentUser} -c "bash /tmp/UninstallLync2.sh"
else
echo "Problem in creating file: \"$OUTFILE\""
fi
}
# This method also works for generating
#+ C programs, Perl programs, Python programs, Makefiles,
#+ and the like.
# Commence the domino effect.
rootCMDs
exit 0
# -----------------------------------------------------------
干杯!