欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

我在 jamf 中 策略中执行 其它策略 ,,,在其它策略(id 为 251 )中 ,,有 (/usr/bin/osascript) 这个代码,,,在251 的策略中,需要执行 (/usr/bin/osascript) 但是 本策略中 不需要执行 (/usr/bin/osascript) AG chatgpt 有大用 有大大用

我在 jamf 中 策略中执行 其它策略

本策略代码如下

#!/bin/bash

#

sudo -E jamf policy -id 251   # 251 是搜狗拼音策略的 id  


在其它策略(id 为 251 和  -id 为 231   )中 ,,有   (/usr/bin/osascript)  这个代码,,,在251 和 231 的策略中,需要执行  (/usr/bin/osascript)

但是 本策略中 不需要执行  (/usr/bin/osascript)



策略id 为 251 的代码

#!/bin/bash

#

/bin/mkdir -p "${HOME}/Desktop/downloadfromjamf"

cd  "${HOME}/Desktop/downloadfromjamf"

/usr/bin/curl -o "./sogou_pinyin_mac_intel_m1_615b.zip"  http://aaaa.bbbb-ccc.com/util/software/sogou_pinyin_mac_intel_m1_615b.zip

unzip  -o "./sogou_pinyin_mac_intel_m1_615b.zip"

chmod -R 777 "${HOME}/Desktop/downloadfromjamf"

sudo "./sogou_mac_615b.app/Contents/MacOS/SogouInstaller"

(/usr/bin/osascript -e  'display dialog "成功安装搜狗拼音,重启后生效,您可以删除桌面上的downloadfromjamf目录!" buttons {"OK"}   default button "OK"')

#把文件夹权限置为 777  ,让所有人可以删

sudo chmod -R 777 "${HOME}/Desktop/downloadfromjamf/" 

#cd ../

#rm -Rf "${HOME}/Desktop/downloadfromjamf"

sudo spctl --master-disable

exit 0


你的目标是:

  • 在调用 jamf policy -id 251 时正常执行策略(包括 /usr/bin/osascript 弹窗)。

  • 但在主脚本中(调用 251 的主策略)禁止运行 osascript

以下是几种解决方法,从最推荐到最彻底:


方法 1(推荐):修改子策略 251,增加环境变量判断  # OK OOK  有大用 有大大用

直接修改 251 策略的脚本,使其仅在 SKIP_OSASCRIPT 未设置时运行弹窗:# OK OOK 有大用 有大大用

bash
#!/bin/bash # ...(前面的代码不变) # 仅当未设置 SKIP_OSASCRIPT 时才弹窗 if [[ -z "$SKIP_OSASCRIPT" ]]; then    /usr/bin/osascript -e 'display dialog "成功安装搜狗拼音,重启后生效,您可以删除桌面上的downloadfromjamf目录!" buttons {"OK"} default button "OK"' fi sudo chmod -R 777 "${HOME}/Desktop/downloadfromjamf/" sudo spctl --master-disable exit 0

然后在你的主脚本中:  # OK OOK 有大用 有大大用

sudo 默认会清除环境变量

macOS 的 sudo 默认启用 env_reset 选项,会丢弃所有用户自定义的环境变量(除非明确配置允许继承)。


jamf policy 以 root 权限运行

即使不用 sudo,jamf policy 自身也会以 root 权限执行,继承的环境变量可能被过滤。

解决方案: 方法 1:通过 sudo 显式传递变量  #  -E  (environment ) 保留当前用户环境变量   # OK  有大用 有大大用



bash
#!/bin/bash export SKIP_OSASCRIPT=1  # 阻止 251 弹窗 sudo -E jamf policy -id 251

优点

  • 最干净、最可控的方式。

  • 不影响其他系统功能。


方法 2:运行时拦截 osascript(仅限当前 shell)

如果无法修改 251,可以临时替换 osascript

bash
#!/bin/bash # 临时伪造 osascript 函数 osascript() {    echo "Skipping osascript (主策略拦截)" >&2 } export -f osascript # 执行 JAMF 策略(251/231 仍会正常弹窗) sudo -E jamf policy -id 251 sudo -E jamf policy -id 231

限制

  • 仅对 bash/zsh 有效,部分情况可能失效(如 sudo 环境)。


方法 3:PATH 重定向(更强拦截)

bash
#!/bin/bash # 1. 创建假的 osascript mkdir -p /tmp/fakebin echo '#!/bin/sh' > /tmp/fakebin/osascript echo 'echo "Skipping osascript" >&2' >> /tmp/fakebin/osascript chmod +x /tmp/fakebin/osascript # 2. 优先使用假命令 export PATH="/tmp/fakebin:$PATH" # 3. 执行 JAMF 策略(251/231 不受影响) sudo -E jamf policy -id 251 sudo -E jamf policy -id 231 # 4. 恢复 PATH(可选) unset PATH

优点

  • 拦截更彻底,但仍不影响子进程。


方法 4(核武器):完全禁用 osascript(不建议)

bash
#!/bin/bash # 1. 备份原版 osascript sudo mv /usr/bin/osascript /usr/bin/osascript.bak # 2. 替换成空命令 echo '#!/bin/sh' | sudo tee /usr/bin/osascript sudo chmod +x /usr/bin/osascript # 3. 执行策略(251/231 不会弹窗) sudo -E jamf policy -id 251 sudo -E jamf policy -id 231 # 4. 恢复原版 sudo mv /usr/bin/osascript.bak /usr/bin/osascript

⚠️ 风险

  • 可能破坏依赖 osascript 的系统功能。

  • 恢复时可能因权限问题失败。

  • SIP 开启时可能无法修改。


总结建议

方法适用场景风险可控性
修改子策略 (方法1)最佳长期方案100%
环境变量拦截 (方法2)快速临时方案可能失效
PATH 重定向 (方法3)强拦截,兼容性好极小
替换二进制 (方法4)终极手段

最终推荐脚本

bash
#!/bin/bash # 方法1(需修改251策略) export SKIP_OSASCRIPT=1 sudo -E jamf policy -id 251 sudo -E jamf policy -id 231 # 或方法3(不需修改251) mkdir -p /tmp/fakebin echo '#!/bin/sh' > /tmp/fakebin/osascript echo 'exit 0' >> /tmp/fakebin/osascript chmod +x /tmp/fakebin/osascript export PATH="/tmp/fakebin:$PATH" sudo -E jamf policy -id 251 sudo -E jamf policy -id 231

采用 方法1 或 方法3 可稳定解决,同时避免系统风险!



#!/bin/bash

export SKIP_OSASCRIPT=1  # 阻止 251 弹窗

sudo -E  jamf policy -id 251

sudo -E jamf policy -id 231

这段代码后面 我还想执行 /usr/bin/osascript 

如果你想在 执行完 sudo -E jamf policy -id 251 后 恢复 osascript 功能,以便后续可以正常调用 /usr/bin/osascript,以下是几种解决方案:


1. 临时禁用 SKIP_OSASCRIPT(推荐)  # OK OOK  有大用 有大大用

bash
#!/bin/bash # 阻止 251/231 弹窗 export SKIP_OSASCRIPT=1 sudo -E jamf policy -id 251 sudo -E jamf policy -id 231 # 恢复 osascript 功能 unset SKIP_OSASCRIPT # 后续正常执行 osascript /usr/bin/osascript -e 'display dialog "This will now run normally!" buttons {"OK"}'

工作原理

  • export SKIP_OSASCRIPT=1 让 251/231 跳过弹窗。

  • unset SKIP_OSASCRIPT 恢复 osascript 功能。

  • 此后所有的 /usr/bin/osascript 调用都不会被拦截。

前提:需要修改 251 策略(增加 if [[ -z "$SKIP_OSASCRIPT" ]] 判断)。




下面的所有的其实已经可以不看了



**2. PATH 重定向(无需修改 251)

bash
#!/bin/bash # 创建假的 osascript(临时跳过) mkdir -p /tmp/fakebin echo '#!/bin/sh' > /tmp/fakebin/osascript echo 'echo "Skipping osascript" >&2' >> /tmp/fakebin/osascript chmod +x /tmp/fakebin/osascript # 仅当前脚本优先用假 osascript export PATH="/tmp/fakebin:$PATH" # 执行策略(251/231 不会触发弹窗) sudo -E jamf policy -id 251 sudo -E jamf policy -id 231 # 恢复原本的 PATH(使 osascript 恢复正常) export PATH="${PATH#/tmp/fakebin:}" # 现在可以正常执行 osascript /usr/bin/osascript -e 'display dialog "Now working normally!" buttons {"OK"}' # 清理假的 osascript(可选) rm -rf /tmp/fakebin

优点

  • 不需要修改 251 策略。

  • 仅临时拦截,不影响全局。


3. 通过 function 临时覆盖

bash
#!/bin/bash # 备份原版 osascript original_osascript="$(which osascript)" # 定义临时替代函数 osascript() {    echo "Skipping osascript for jamf policies" >&2    return 0 } export -f osascript # 251/231 不会弹窗 sudo -E jamf policy -id 251 sudo -E jamf policy -id 231 # 恢复原版 osascript osascript() {    "$original_osascript" "$@" } export -f osascript # 现在可以正常调用 /usr/bin/osascript -e 'display dialog "Back to normal!" buttons {"OK"}'

限制:仅对 bash/zsh 有效,若有子 shell 可能失效。


**4. **exec 恢复

如果是在 jamf 策略执行后 完全恢复系统 osascript(例如之前修改过 /usr/bin/osascript):

bash
#!/bin/bash # 如果是方法4(替换了二进制),恢复原版: if [ -f /usr/bin/osascript.bak ]; then    sudo mv /usr/bin/osascript.bak /usr/bin/osascript fi # 现在 osascript 完全恢复 /usr/bin/osascript -e 'display dialog "System osascript is back!" buttons {"OK"}'

⚠️ 仅用于极端情况(避免替换系统二进制文件)。


最佳方案总结

✅ 如果 251 可修改 → 方法1(最干净可控):# OK 有大用 
✅ 如果 251 不可修改 → 方法2PATH 临时伪冒):
✅ 如果运行环境可控(非 sudo → 方法3(临时 function 覆盖):
⛔ 避免直接修改 /usr/bin/osascript → 方法4(风险高)。

你更倾向于哪一种?我可以提供更具体的实现。


export SKIP_OSASCRIPT=1 是什么 意思

export SKIP_OSASCRIPT=1 是一条 Bash 环境变量设置命令,意思是:

定义一个名为 SKIP_OSASCRIPT 的环境变量,并赋值为 1(相当于 true/启用),之后所有子进程都会继承这个变量。

它的核心作用

  1. 定义规则
    SKIP_OSASCRIPT=1 本质上是一个 标志位(类似开关),可以被脚本检测到。

  2. 后续影响
    通过 export 导出后,所有从这个 shell 启动的子进程(包括 sudo -E jamf policy)都能读取这个变量。


在你的场景中的用途

bash
export SKIP_OSASCRIPT=1         # 临时启用 "跳过osascript" 模式 sudo -E jamf policy -id 251        # 251策略会检测这个变量,决定是否弹窗 sudo -E jamf policy -id 231        # 同上 unset SKIP_OSASCRIPT            # 关闭跳过模式 /usr/bin/osascript ...          # 现在可以正常执行osascript
  • 关键前提251 和 231 的脚本需要 主动检查这个变量(见下文说明)。


如何让子策略检测 SKIP_OSASCRIPT

在你的 251 策略脚本中,需要添加判断逻辑:

bash
#!/bin/bash # ...原有的安装代码... # 只有 SKIP_OSASCRIPT 未设置时才会弹窗 if [[ -z "${SKIP_OSASCRIPT}" ]]; then    /usr/bin/osascript -e 'display dialog "安装成功!" buttons {"OK"}' fi
  • -z "$SKIP_OSASCRIPT" 表示:如果变量不存在或为空,才执行弹窗。

  • 当主脚本设置了 export SKIP_OSASCRIPT=1,子脚本会跳过弹窗。


类比理解

命令类比现实场景
SKIP_OSASCRIPT=1告诉所有人:"今天静音,不要播放声音"
export用广播宣布这条规则(让所有房间生效)
if [[ -z "$SKIP_OSASCRIPT" ]]每个房间检查:"如果没听到静音广播,就正常播放声音"

注意事项

  1. 作用范围

  • 只对 显式检查该变量的脚本 有效(如果子策略不检查,则无效)。

  • 进程结束后,变量自动失效(除非写入 ~/.bashrc 等配置文件)。

  • 变量名自定义

    • 你可以改用其他名字(如 DISABLE_DIALOGS=1),只需保持父子脚本一致。

  • 与 sudo 的关系

    • sudo 默认会重置环境变量,但 jamf 通常能继承变量(建议测试验证)。


    其他典型用途

    类似的环境变量模式还用于:

    bash
    export DEBUG=1          # 启用调试模式 export CI=true          # 告诉脚本当前是自动化环境 export NO_COLOR=1       # 禁用彩色输出

    如果需要更强制性的拦截,建议结合我之前提到的 PATH 重定向或函数覆盖方案。


    unset SKIP_OSASCRIPT 是什么意思

    unset SKIP_OSASCRIPT 是 删除/取消 之前定义的 SKIP_OSASCRIPT 环境变量,使其不再影响后续进程。相当于 关闭 这个开关。


    详解

    1. 它做了什么?

    • 撤销定义
      移除当前 shell 中名为 
      SKIP_OSASCRIPT 的变量,此后任何读取该变量的操作都会返回空值。

    • 作用域
      仅影响 当前终端会话,不会持久化到系统配置。

    2. 典型使用场景(结合你的例子)

    bash
    export SKIP_OSASCRIPT=1    # 设置变量(开启跳过模式) sudo -E jamf policy -id 251   # 子策略检测到变量,跳过弹窗 sudo -E jamf policy -id 231   # 同上 unset SKIP_OSASCRIPT       # 删除变量(关闭跳过模式) /usr/bin/osascript -e '...' # 现在会正常执行弹窗

    3. 对比其他操作

    命令作用类比
    SKIP_OSASCRIPT=1定义变量(仅当前 shell)临时写个便签
    export SKIP_OSASCRIPT=1导出变量(子进程可见)用广播通知所有人
    unset SKIP_OSASCRIPT删除变量撕掉便签 / 关闭广播

    实际效果验证

    bash
    # 设置变量 export SKIP_OSASCRIPT=1 echo $SKIP_OSASCRIPT    # 输出: 1 # 删除变量 unset SKIP_OSASCRIPT echo $SKIP_OSASCRIPT    # 输出: (空)

    常见问题

    Q: 如果忘记 unset 会怎样?
    A: 变量会一直存在,直到关闭终端或启动新的 shell 会话。可能导致后续脚本误判。

    Q: 和 export SKIP_OSASCRIPT=(赋空值)有什么区别?
    A: 赋空值后变量仍存在(值为空),而 unset 是完全删除变量。测试时需注意:

    bash
    export SKIP_OSASCRIPT= [[ -v SKIP_OSASCRIPT ]] && echo "存在"   # 输出: 存在(变量未删除) unset SKIP_OSASCRIPT [[ -v SKIP_OSASCRIPT ]] && echo "存在"   # 无输出(变量已删除)

    最佳实践

    1. 对称操作
      像开关一样成对使用:

      bash
      export SKIP_OSASCRIPT=1   # 开启 # ...执行需要跳过的代码... unset SKIP_OSASCRIPT      # 关闭
    2. 脚本安全性
      在脚本结束时主动清理变量:

      bash
      #!/bin/bash export SKIP_OSASCRIPT=1 trap 'unset SKIP_OSASCRIPT' EXIT  # 确保脚本退出时删除变量
    3. 调试技巧
      检查变量状态:

      bash
      if [[ -v SKIP_OSASCRIPT ]]; then    echo "变量存在" else    echo "变量不存在" fi

    如果需要更复杂的变量管理(如跨终端持久化),可考虑写入临时文件或使用 envchain 等工具。



    [[ -v SKIP_OSASCRIPT ]] 与  [[ -z "$SKIP_OSASCRIPT" ]] 区别


    [[ -v SKIP_OSASCRIPT ]] 和 [[ -z "$SKIP_OSASCRIPT" ]] 是 两种完全不同的变量检查逻辑,区别如下:


    1. [[ -v SKIP_OSASCRIPT ]]

    功能

    检查变量 SKIP_OSASCRIPT 是否被定义(存在),不关心变量的值

    • 返回 true:只要变量被定义过(即使值为空 "" 或 0)。

    • 返回 false:变量完全未被定义(从未 export 或赋值过)。

    示例

    bash
    unset SKIP_OSASCRIPT  # 确保变量未定义 [[ -v SKIP_OSASCRIPT ]] && echo "定义" || echo "未定义"  # 输出:未定义 export SKIP_OSASCRIPT=""  # 定义为空值 [[ -v SKIP_OSASCRIPT ]] && echo "定义" || echo "未定义"  # 输出:定义

    2. [[ -z "$SKIP_OSASCRIPT" ]]

    功能

    检查变量 SKIP_OSASCRIPT 的值是否为空(或未定义)。

    • 返回 true:变量值为空 ""  变量未定义。

    • 返回 false:变量有非空值(如 1truehello)。

    示例

    bash
    unset SKIP_OSASCRIPT  # 变量未定义 [[ -z "$SKIP_OSASCRIPT" ]] && echo "空或未定义" || echo "有值"  # 输出:空或未定义 export SKIP_OSASCRIPT="" [[ -z "$SKIP_OSASCRIPT" ]] && echo "空或未定义" || echo "有值"  # 输出:空或未定义 export SKIP_OSASCRIPT=1 [[ -z "$SKIP_OSASCRIPT" ]] && echo "空或未定义" || echo "有值"  # 输出:有值

    关键区别总结

    检查方式关注点true 条件典型用途
    [[ -v VAR ]]变量是否定义变量存在(即使值为空)检查可选配置是否被设置
    [[ -z "$VAR" ]]变量值是否为空变量未定义  值为空检查用户是否提供了有效输入

    你的应用场景

    场景 1:需要精确控制弹窗

    bash
    # 只有当 SKIP_OSASCRIPT 完全未定义时才弹窗 if [[ ! -v SKIP_OSASCRIPT ]]; then    /usr/bin/osascript -e 'display dialog "弹窗"' fi

    场景 2:允许空值但阻止弹窗

    bash
    # 如果 SKIP_OSASCRIPT 非空(如值为1),则跳过弹窗 if [[ -z "$SKIP_OSASCRIPT" ]]; then    /usr/bin/osascript -e 'display dialog "弹窗"' fi

    常见误区

    1. 混淆定义与值

    • [[ -v SKIP_OSASCRIPT ]] → true(变量存在)

    • [[ -z "$SKIP_OSASCRIPT" ]] → true(值为空)

    • -v 检测的是变量是否存在,而 -z 检测的是值是否为空。

    • 例如:export SKIP_OSASCRIPT=""

  • 未定义 vs 空值

    bash
    unset SKIP_OSASCRIPT [[ -v SKIP_OSASCRIPT ]]      # false(未定义) [[ -z "$SKIP_OSASCRIPT" ]]   # true(未定义视为空)

  • 最佳实践

    • 需要严格区分“未设置”和“空值” → 用 -v

    • 只关心“是否有有效值” → 用 -z

    • 防御性脚本:结合两者:

      bash
      if [[ ! -v SKIP_OSASCRIPT ]] || [[ -z "$SKIP_OSASCRIPT" ]]; then    echo "变量未定义或值为空" fi


    export SKIP_OSASCRIPT=1    # 设置变量(开启跳过模式)

    sudo -E  jamf policy -id 251   # 子策略检测到变量,跳过弹窗

    sudo -E  jamf policy -id 231   # 同上

    为什么此时的变量 SKIP_OSASCRIPT 并没有传到 策略 251 里面


    你是对的:通过 sudo -E jamf policy -id 251 调用子策略时,SKIP_OSASCRIPT 变量默认不会传递,因为 sudo 会重置环境变量(出于安全考虑)。以下是详细解释和解决方案:


    原因分析

    1. sudo 默认会清除环境变量
      macOS 的 sudo 默认启用 env_reset 选项,会丢弃所有用户自定义的环境变量(除非明确配置允许继承)。

    2. jamf policy 以 root 权限运行
      即使不用 sudojamf policy 自身也会以 root 权限执行,继承的环境变量可能被过滤。


    解决方案

    方法 1:通过 sudo 显式传递变量  # -E  (environment ) 保留当前用户环境变量   # OK  有大用 有大大用

    bash
    export SKIP_OSASCRIPT=1 sudo -E jamf policy -id 251  # -E 保留当前用户环境变量
    • -E 参数:让 sudo 继承调用者的所有环境变量。

    • 限制:需在 /etc/sudoers 中允许该选项(默认通常允许)。


    方法 2:通过 env 直接传递

    bash
    export SKIP_OSASCRIPT=1 sudo env SKIP_OSASCRIPT="$SKIP_OSASCRIPT" jamf policy -id 251
    • env VAR=value command:临时为命令设置变量,绕过 sudo 的限制。


    方法 3:修改 /etc/sudoers(不推荐)

    bash
    # 允许所有变量通过 sudo(安全性降低) sudo visudo

    添加以下行:

    Defaults env_keep += "SKIP_OSASCRIPT"
    
    • 风险:降低系统安全性,仅建议在受控环境使用。


    方法 4:通过脚本参数传递(最可靠)

    如果能够修改 251 和 231 策略的脚本,可以通过参数传递:

    bash
    sudo -E jamf policy -id 251 -skipDialogs  # 假设子策略支持参数

    然后在子策略脚本中:

    bash
    if [[ "$1" == "-skipDialogs" ]]; then    echo "跳过弹窗" fi

    验证变量是否传递

    在 251 策略的脚本中临时添加调试代码:

    bash
    #!/bin/bash echo "SKIP_OSASCRIPT 的值是: [${SKIP_OSASCRIPT}]"  # 检查变量是否传递

    运行后查看日志:

    bash
    tail -f /var/log/jamf.log

    最终推荐方案

    bash
    #!/bin/bash export SKIP_OSASCRIPT=1 # 方法1(需 sudoers 允许) sudo -E jamf policy -id 251 # 或方法2(兼容性更好) sudo env SKIP_OSASCRIPT="$SKIP_OSASCRIPT" jamf policy -id 251 # 后续可正常使用 osascript unset SKIP_OSASCRIPT /usr/bin/osascript -e 'display dialog "Now working!"'

    为什么其他方法无效?

    • export 仅对当前 Shell 及其子进程有效,而 sudo 会创建新环境。

    • Jamf 策略执行上下文:子策略可能运行在不同的 Shell 或 Root 环境下。

    通过以上方法,可确保变量正确传递到子策略。如果仍有问题,可能是策略脚本未正确检测变量(需检查 251 的脚本逻辑)。


    普通分类: