从 bash 脚本中触发通知
Triggering a notification from within a bash script
目标设备:macOS Catalina 及更高版本
我可以使用一些帮助解决脚本中的问题,该脚本应该在用户尝试连接到被禁止的 SSID 时触发 osascript 通知。只有当用户已经连接或正在尝试连接到被禁止的 SSID 之一时,才会出现通知。
虽然问题是由于脚本正在 运行 启动,运行ning 也是如此,但是,即使在 运行ning 之后作为登录用户的通知命令,即使脚本的其余部分工作正常,也不会发生通知。
其次,我们也无法从本地项目钥匙串中删除被禁止的 SSID 的凭据,但实际上,该脚本具有预期的效果,可以在连接时将机器踢出被禁止的网络并防止机器自动将来连接。我们能够从系统钥匙串中删除凭据,但最好找到一种方法也能从本地项目钥匙串中删除该项目。
无论如何,主要问题出现在下面修改代码的第 47 行。如果您能帮助解决这些问题中的任何一个,我们将不胜感激。
此代码段已修改为更容易识别违规命令:
#
# This script will find all saved SSIDs, compare them to a list of banned SSIDs and if found, removes them
#
# If the client is connected to a banned SSID, Wi-Fi is toggled to allow automatic connection to a non-banned SSID
#
# Script is only able to remove SSID from System keychain as delete-generic-password is not "Local Items" aware
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Change Internal Field Seperator to " " to allow for SSIDs that contain spaces in array "bannedNetworks"
IFS=' '
# Get current logged in user
loggedInUser=`ls -l /dev/console | cut -d " " -f 4`
# Determine the Wi-Fi interface
interface=$(networksetup -listallhardwareports | grep -E '(Wi-Fi|AirPort)' -A 1 | grep -o en.)
# Get all saved SSIDs
savedNetworks=($(networksetup -listpreferredwirelessnetworks $interface | tail -n +2))
# SSIDs to be removed
bannedNetworks=("SSIDone" "SSIDtwo" "SSIDthree")
# Power cycle wireless adapter if connected to a banned network, then remove it
for i in "${bannedNetworks[@]}"
do
if [[ $(networksetup -getairportnetwork $interface | cut -d ":" -f 2 | cut -c 2-) != $i ]]; then
echo "Not connected to $i"
else
networksetup -removepreferredwirelessnetwork $interface $i
sudo security delete-generic-password -l $i "/Library/Keychains/System.keychain" >/dev/null 2>&1
# Update savedNetworks variable to prevent "…not found" error as the connected network has already been removed yet remains in the array
savedNetworks=($(networksetup -listpreferredwirelessnetworks $interface | tail -n +2))
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Notify the user: Doesn't trigger properly, even when run as the logged in user
sudo -u $loggedInUser osascript -e 'display notification "The Wi-Fi network you selected is not for use with district devices. If \"ApprovedNetwork\" fails, please use \"BackupNetwork.\"" with title "Blocked Network"'
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
networksetup -setairportpower $interface off
sleep 5
networksetup -setairportpower $interface on
fi
done```
好吧,您遇到的来自守护程序的通知问题是设计使然的。
这与macOS如何处理不同的会话有关,您可以阅读here and here了解更多信息。
你现在需要知道的是,当 运行 作为守护进程时,即使使用 sudo -u,你也没有默认访问用户 GUI 会话的权限。
但是,有一些方法可以从您的上下文中访问用户 GUI 会话,正如所描述的那样 here
综上所述,您需要做的是:
- 改变
sudo -u $loggedInUser osascript -e ...
到
sudo launchctl asuser $userId osascript -e ...
$userId 是这样的:
userId=`sudo -u $USER id -u`
(我不是很喜欢bash,可以用更清晰的方式来完成)
- 检查 sh 是否在安全首选项中被授予完整磁盘访问权限(或者沙盒配置文件不允许您读取 sh 脚本)
目标设备:macOS Catalina 及更高版本
我可以使用一些帮助解决脚本中的问题,该脚本应该在用户尝试连接到被禁止的 SSID 时触发 osascript 通知。只有当用户已经连接或正在尝试连接到被禁止的 SSID 之一时,才会出现通知。
虽然问题是由于脚本正在 运行 启动,运行ning 也是如此,但是,即使在 运行ning 之后作为登录用户的通知命令,即使脚本的其余部分工作正常,也不会发生通知。
其次,我们也无法从本地项目钥匙串中删除被禁止的 SSID 的凭据,但实际上,该脚本具有预期的效果,可以在连接时将机器踢出被禁止的网络并防止机器自动将来连接。我们能够从系统钥匙串中删除凭据,但最好找到一种方法也能从本地项目钥匙串中删除该项目。
无论如何,主要问题出现在下面修改代码的第 47 行。如果您能帮助解决这些问题中的任何一个,我们将不胜感激。
此代码段已修改为更容易识别违规命令:
#
# This script will find all saved SSIDs, compare them to a list of banned SSIDs and if found, removes them
#
# If the client is connected to a banned SSID, Wi-Fi is toggled to allow automatic connection to a non-banned SSID
#
# Script is only able to remove SSID from System keychain as delete-generic-password is not "Local Items" aware
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Change Internal Field Seperator to " " to allow for SSIDs that contain spaces in array "bannedNetworks"
IFS=' '
# Get current logged in user
loggedInUser=`ls -l /dev/console | cut -d " " -f 4`
# Determine the Wi-Fi interface
interface=$(networksetup -listallhardwareports | grep -E '(Wi-Fi|AirPort)' -A 1 | grep -o en.)
# Get all saved SSIDs
savedNetworks=($(networksetup -listpreferredwirelessnetworks $interface | tail -n +2))
# SSIDs to be removed
bannedNetworks=("SSIDone" "SSIDtwo" "SSIDthree")
# Power cycle wireless adapter if connected to a banned network, then remove it
for i in "${bannedNetworks[@]}"
do
if [[ $(networksetup -getairportnetwork $interface | cut -d ":" -f 2 | cut -c 2-) != $i ]]; then
echo "Not connected to $i"
else
networksetup -removepreferredwirelessnetwork $interface $i
sudo security delete-generic-password -l $i "/Library/Keychains/System.keychain" >/dev/null 2>&1
# Update savedNetworks variable to prevent "…not found" error as the connected network has already been removed yet remains in the array
savedNetworks=($(networksetup -listpreferredwirelessnetworks $interface | tail -n +2))
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Notify the user: Doesn't trigger properly, even when run as the logged in user
sudo -u $loggedInUser osascript -e 'display notification "The Wi-Fi network you selected is not for use with district devices. If \"ApprovedNetwork\" fails, please use \"BackupNetwork.\"" with title "Blocked Network"'
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
networksetup -setairportpower $interface off
sleep 5
networksetup -setairportpower $interface on
fi
done```
好吧,您遇到的来自守护程序的通知问题是设计使然的。
这与macOS如何处理不同的会话有关,您可以阅读here and here了解更多信息。
你现在需要知道的是,当 运行 作为守护进程时,即使使用 sudo -u,你也没有默认访问用户 GUI 会话的权限。
但是,有一些方法可以从您的上下文中访问用户 GUI 会话,正如所描述的那样 here
综上所述,您需要做的是:
- 改变
sudo -u $loggedInUser osascript -e ...
到
sudo launchctl asuser $userId osascript -e ...
$userId 是这样的:
userId=`sudo -u $USER id -u`
(我不是很喜欢bash,可以用更清晰的方式来完成)
- 检查 sh 是否在安全首选项中被授予完整磁盘访问权限(或者沙盒配置文件不允许您读取 sh 脚本)