替代用户mid-Bash-script&继续运行命令(Mac OSX)

时间:2016-04-12 00:17:51

标签: arrays macos bash unix keychain

我正在构建两个脚本,它们将完全卸载Mac OS X上的程序(Microsoft Lync)。我需要能够从具有root访问权限的帐户(此帐户最初执行第一个脚本)进行交换当前登录的用户。

这是必要的,因为第二个脚本不仅需要由登录用户执行,还需要由所述用户的shell执行。在此示例中,这两个脚本的名称为Uninstall1.shUninstall2.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 $1}' | 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不允许从管理员帐户修改其他用户的钥匙串(相关管理员帐户具有超级用户权限,但不是也不会切换根)。 -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 $2, $3}' | sed -e 's/"//')
   security delete-generic-password -l "${lyncPW}"
}


rmFiles


在上面的脚本中,rmFiles通过从用户的~/Library目录中删除一些文件和目录来关闭脚本。假设来自su的{​​{1}}使用本地用户的shell正确执行第二个脚本,这没有问题。

然后我使用Uninstall1.sh转储本地用户的shell,找到一个特定的证书,然后将所有结果分配给security dump-keychain数组(因为用户可能会重复此项目&#39} ; s钥匙串)。然后删除数组中的每个项目,之后动态查找和删除更多的钥匙串项目。

我发现的第一个脚本将正确cLen到它找到的登录用户,此时第二个脚本根本不运行。或者,第二个脚本以root用户身份运行,因此无法从登录用户{@ 1}}中正确删除钥匙串项。

对不起,很长的帖子,感谢阅读,我期待着对这种情况有所了解!

1 个答案:

答案 0 :(得分:0)

<强>修订
我设法找到一种方法来实现我在单个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 $2, $3}' | 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 $1}' | 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

# -----------------------------------------------------------


干杯!