OSX: 让狮子说中文

最后更新于:2022-04-01 10:57:05

注:刚才居然被删除了,头一次,现在还没有得到任何的删除理由。这么一个应用blog,也有人删,莫名其妙。只能是贴上副本了。 我们都知道,很多的OS X应用程序都支持语音播放功能,比如说在Safari中,选中菜单Edit->Speech->Start Speaking,它可以使用系统当前的语音语速,朗读当前访问的web网页。但是在Lion之前的系统,这个功能只支持西文的,没有中文,要想让它识别 并朗读其他文种,需要购买第三方的软件,至于什么软件,搜索了一下,没有什么结果。好消息是,现在, Lion已经内置支持了(*_*)。如何使用呢?下面让我们一步一步地来做: ### **安装语音库** 要让Lion系统说中文,就要有中文语音库,语音库主要是把文本内容对应到一个发音上。 在系统首次安装时,并不包括这些语音库,所以首先要下载安装中文语音库。进入系统偏好设置的语音,再选中“文本至语音”标签,点击“系统嗓音”的列表,最初看到的是英文的语音列表, ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-19_57158f519dcce.gif) 接着,选择“自定…”,这里就有多国语言的语音库了, 可以发现,每个语种可能有多个名字在列表中,这是因为每个语音库使用的是特定的“真人”嗓音,基本的分为男女,还可以细分不同人的嗓音。目前为止,中文的有普通话Ting-Ting,香港的Sin-Ji,台湾的Ya-Ling。Ting-Ting的嗓音相当清楚,Ya-Ling的也好听,香港的是广东话,她们都是女声。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-19_57158f51d4bb4.gif) 选择好后,每个需要下载的语音后面又一个黄色的三角叹号标志,它提醒你,这个语音库没有在本地硬盘上,需要下载,所有的这三个中文语音库都需要下载。 按“好”按钮,它会提示你是否下载安装,然后是软件许可协议,如果你不同意就无法安装。如果下载顺利,那么很快就会安装完毕。Tony Liu 2011.07 ### **配置** 安装完了,首先来测试一下吧,按播放按钮。 如果下载安装后,系统嗓音不是中文的,那么点击“系统嗓音”列表,选中一个中文嗓音,按“好”就设定系统默认嗓音了。 最好是选择打开“按下按键时朗读所选文本”,这样在任何支持的程序中,按option-Esc组合键就可以播放语音,再按停止播放,否则,需要到菜单中去选择,开始和停止播放。 如果需要,可以调节语速的。Tony Liu 2011.07 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-19_57158f51ef698.gif) ### **使用** 最简单的可以让他来为你读任何的中文文件。当然了你需要使用支持语音的软件,比如便签,文本编辑器,预览和Safari等等。 对PDF文档,用预览打开,让它读给你听。 Safari的网页当然可以,不过,还记得Safari有个阅读器吗?使用它和语音,可以让电脑给你读新闻。 想学外语吗?让它读给你。 大家可以找找,看看它有没有发音错误或者不准的字。如果找到了,就到苹果官方的bugreport(http://bugreport.apple.com)上提交错误报告,不过它需要你首先有一个帐号。 ### **卸载** 如果刚才为了测试,下载了多余的语音库怎么办? 如果你不在意它占用你的硬盘空间,那么好,留着它;如果你想至少在系统嗓音列表中看不见它,那么就回到“自定…” 中,去掉该语音库前面的对勾;如果你需要把语音库删除,以腾出空间来(Ting-Ting的要600多MB,Ya-Ling的400多,Sin-Ji的也要300多,全部加起来要1个多GB),因为目前为止,苹果官方还没有提供官方解决方案,这里提供一个方法,可以删除这些语音文件库,这个方法相当的有效,但是目前没有获得安装程序文件,不得而知该安装程序是否对其他的系统文件做了修改,所以有可能删除的不完全,不过经过测试可以肯定的是,其他的即便有也是一些很小的改动。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-19_57158f5216984.gif) 首先,退出系统偏好设置,然后在Finder中,进入系统->资源库->Speech->Voices文件夹,在里面你回看见以那些语音库为名字的文件夹,比如Ya-Ling.SpeechVoice和Ya-LingCompact.SpeechVoice,Sin-Ji.SpeechVoice,以及Ting-Ting.SpeechVoice和Ting-TingCompact.SpeechVoice。我门所要做的就是把你不想要的语音库目录都删除。删除的时候系统要求你进行管理员验证的。删除完了,再回到“语音”中,你会发现,删除的已经不在列表上了,如果再次选中,系统还会要求你下载安装。   ### **题外话:** 这个语音库能否在Snow Leopard上使用呢?刚才测试了,应该是不行。细看里面的内容,SnowLeopard系统所携带的语音库的版本和Lion中的明显的不同,所以,可能这种移植尝试是不值得的了。 Tony Liu 2011.07  
';

OSX:Lion支持登录窗口的Policy Banner

最后更新于:2022-04-01 10:57:03

在显示登录窗口之前显示一个使用说明/规则,在如同在XP中支持的那样,是企业管理中的一个很好的管理措施。 把你的Policy内容编辑成PolicyBanner.rtf, txt或者rtfd文件,然后保存在/Library/Security/里面。
';

OS X: 实用脚本程序(bash scripts)系列-14

最后更新于:2022-04-01 10:57:01

显示所有服务是否开启的状态(System Preferences->Sharing) 运行logger.sh程序, ~~~ #!/bin/bash # Logger, software to display information about the "divisions" in Mac OS X [10.6] # 2011-05-31 / Peter Morller, Computer Science # Version 0.2 # Moved to / usr / bin (from / bin) # 2011-06-13,14: bugfix help() {   echo   echo "Usage: $0 [-u]"   echo   echo "-u: Update the script"   echo   echo "If run by root: datafiles in /Library/OpenPorts are created, but no output."   echo "If run by any other user: output is displayed based on those datafiles."   echo   echo "This script is supposed to be used in conjunction with a launchd-component, se.lth.cs.open_ports,"   echo "that creates the datafiles in /Library/OpenPorts every two minutes. The use of GeekTool to display the result"   echo "is also part of the idea behind this script!"   exit 0 } # Locating an IP address. Publishes: locate_ip() {   curl http://www.geoiptool.com/en/?IP=$1 2>/dev/null | awk '   /<td.*>(Country:|City)/ {   record="t";gsub("[\t ]*<[^>]*>",""); printf("%-1s ",$0);next;   }   record == "t" { gsub("[\t ]*<[^>]*>[\t ]*","");print $0;record="f";next}   {next}   END{print ""}'   } # Check if $ IP's $ IP_CACHE and dig out $ $ Country and City # If not, look it up and update $ IP_CACHE # Provides: $ $ Country & City (and updates $ IP_CACHE) check_ip() {   if [ "`grep "$IP:" $IP_CACHE`" ]; then     #say "Found address in cache"     City=`grep "$IP:" $IP_CACHE | cut -d: -f3`     Country=`grep "$IP:" $IP_CACHE | cut -d: -f2`   else     #say "Performing a lookup"     locate_ip "$IP" | iconv --from-code=ISO-8859-1 --to-code=UTF-8 > "$IP_LOCATE_CACHE"     City=`grep "City" "$IP_LOCATE_CACHE" | awk '{ print $2" "$3" "$4 }' | sed 's/\ *$//g'`     Country=`grep "Country:" "$IP_LOCATE_CACHE" | awk '{ print $2" "$3" "$4 }' | sed 's/\ *$//g'`     echo "$IP:$Country:$City" >> "$IP_CACHE"   fi   } # Call up the DNS for $ IP # Provides: $ HOSTNAME # Also take care of the private addresses: # • 10.x.x.x # • 172.16.x.x # • 192.168.x.x # As well as self-assigned address: # 169.254.x.x GetDNS() {  PrivateAddress="No"  if [ "$(echo "$IP" | cut -d\. -f1)" = "10" ]; then    HOSTNAME="Private address ($IP)"    PrivateAddress="Yes"  elif [ "$(echo "$IP" | cut -d\. -f1,2)" = "172.16" ]; then    HOSTNAME="Private address ($IP)"    PrivateAddress="Yes"  elif [ "$(echo "$IP" | cut -d\. -f1,2)" = "192.168" ]; then    HOSTNAME="Private address ($IP)"    PrivateAddress="Yes"  elif [ "$(echo "$IP" | cut -d\. -f1,2)" = "169.254" ]; then    HOSTNAME="Self-assigned address ($IP)"    PrivateAddress="Yes"  else    HOSTNAME_tmp=`host $IP`    ERR="$?"    if [ ! "$ERR" = "0" ]; then      HOSTNAME="$IP could not be looked up! (DNS timeout)"    else      HOSTNAME=`echo $HOSTNAME_tmp | awk '{ print $NF }' | sed 's/\.$//g'`    fi  fi  } # Exit if there are already running a open_ports if [ "`ps -ef | grep [l]ogger.sh | wc -l`" -gt "2" ]; then   echo "\"logger.sh\" already running -- will exit now"   exit 0 fi # Read parameters: while getopts ":hu" opt; do case $opt in     u ) fetch_new=t;;  \?|h ) help;; esac done # Default values: # PREFIX pointing out where all data files are stored. Change this if PREFIX="/Library/com.any/Logger" # IP_CACHE is a growing list of IP addresses and their geographical locations. Built on post # Because this file is used by other scripts, is it not open the Ports directory IP_CACHE="/Library/com.any/ip_cache.txt" # IP_LOCATE_CACHE save the geographic locations of the computer's exterior (external) address. Temporary IP_LOCATE_CACHE="$PREFIX"/ip_locate_cache.txt SharingFile="$PREFIX"/Sharing.txt # Logfile for Apple File Sharing AFS_Log=/Library/Logs/AppleFileService/AppleFileServiceAccess.log # FieldSeparator indicates IFS file FieldSeparator="_" # String for printf (used for printing EST Relations) Formatstring="%-23s%-4s" # String for printf (used to print lists, links) FormatstringListen="%-6s%-6s%-18s%-15s%6s%2s%-17s%-15s" # (The colors can be found on http://en.wikipedia.org/wiki/ANSI_escape_code, http://graphcomp.com/info/specs/ansi_col.html etc.) Reset="\e[0m" ESC="\e[" RES="0" BoldFace="1" ItalicFace="3" UnderlineFace="4" SlowBlink="5" BlackBack="40" RedBack="41" BlueBack="44" WhiteBack="47" BlackFont="30" RedFont="31" GreenFont="32" YellowFont="33" BlueFont="34" CyanFont="36" WhiteFont="37" # Reset all colors BGColor="$RES" Face="$RES" FontColor="$RES" # Determine defaulinterface and corresponding IP address DEFAULT_INTERFACE=`route get www.lu.se | grep interface | awk '{ print $2 }'` IP_ADDRESS=`ifconfig $DEFAULT_INTERFACE | grep "inet " | awk '{ print $2 }'` #DOMAIN="`ipconfig getpacket en0 | grep 'domain_name (string)' | awk '{ print $3 }'`" #DOMAIN="`hostname | cut -d\. -f2-7`" Host_Name="$(hostname)" Machine_Name="$(hostname -s)" DOMAIN="${Host_Name##$Machine_Name.}" # Check where in the world localhost is: IP="$IP_ADDRESS" check_ip Localhost_Location=" ($Country, $City)" # <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> # # Create input data (if we drive through launchd, $ USER = nil or root), then stop if [ "$USER" = "root" -o -z "$USER" ]; then #set -x   rm "$SharingFile"     ########################   ## Check AFP   ########################   AFP_Share="$(defaults read /var/db/launchd.db/com.apple.launchd/overrides com.apple.AppleFileServer 2> /dev/null | grep [D]isabled | awk '{print $3}' | sed 's/;//g')"   AFP_Verification="$(lsof -i :548)"   if [ "$AFP_Share" = "0" -a -n "$AFP_Verification" ]; then     Share_AFP="t"   else     Share_AFP="f"   fi   AFP_Verification="$(lsof -i :548)"   echo "Apple file share_$(if [ "$Share_AFP" = "t" ]; then echo "ON"; else echo "OFF"; fi)" > "$SharingFile"     # Check the logs and report   # Typical logfile entry (login and logout) set like this:   # IP 90230245202 - - [17/Dec/2010: 09:08:53 0100] "Login Johnnie" 0 0 0   # IP 90230245202 - - [17/Dec/2010: 10:16:09 0100] "Logout Johnnie" 0 0 0   # 1. Is log file?   if [ -f "$AFS_Log" ]; then     # 2. OK, it's there. Is any assembly started?     if [ -n "$(ps -ef | grep [A]ppleFileServer)" ]; then       # 3. Go through the active links       for IP in $(lsof -i :548 -n | grep EST | cut -d\> -f2 | cut -d: -f1); do         # 4. Locate the last log from the machine         LastLine="$(grep " $IP " $AFS_Log | grep \"Login\  | tail -1)"         AuthUser="$(echo $LastLine | awk '{print $8}' | cut -d\" -f1)"         AuthTime="$(echo $LastLine | cut -d\[ -f2 | cut -d\] -f1)"         GetDNS         check_ip         Location=" ($Country, $City)"         # Now we have all the pieces in place: write them in $ file-sharing! #        echo " - mounted by \"$AuthUser\" from $(echo $HOSTNAME | sed s/\.$DOMAIN//g)$(if [ -z "$(echo $HOSTNAME | grep -o $DOMAIN)" ]; then echo " ($City, $Country)"; fi) at ${AuthTime}${FieldSeparator}" >> "$SharingFile"         echo " - mounted by \"$AuthUser\" from ${HOSTNAME%%.$DOMAIN}${Location%%$Localhost_Location} at ${AuthTime}${FieldSeparator}" >> "$SharingFile"       done     fi   else     echo " - NO LOGFILE FOR AFP!! See:${FieldSeparator}" >> "$SharingFile"     echo " - http://com.any/kontakt/peter_moller/unix/applefileserver/${FieldSeparator}" >> "$SharingFile"     echo " - for info on how to enable it!${FieldSeparator}" >> "$SharingFile"   fi   ########################   # # Check SMB   ########################   #SMB_Share="$(defaults read /var/db/launchd.db/com.apple.launchd/overrides org.samba.nmbd 2> /dev/null | grep [D]isabled | awk '{print $3}' | sed 's/;//g')"   SMB_Share="$(grep "enable disk services" /var/db/smb.conf | cut -d= -f2 | sed 's/^\ *//g')"   SMB_Verification_139="$(lsof -i :139)"   SMB_Verification_445="$(lsof -i :445)"   if [ "$SMB_Share" = "yes" -a -n "$SMB_Verification_139" -a -n "$SMB_Verification_445" ]; then     Share_SMB="t"   else     Share_SMB="f"   fi   echo "Samba file share${FieldSeparator}$(if [ "$Share_SMB" = "t" ]; then echo "ON"; else echo "OFF"; fi)" >> "$SharingFile"   # List of those who are logged   SMB_loggfile=/var/log/samba/log.smbd   # Check the logs and report   # Typical logfile (login and logout) looks like this:   # [10/12/2010 16:19:52, 1, pid = 78387] / SourceCache/samba/samba-235.5/samba/source/smbd/service.c: make_connection_snum (1092)   # 130.235.16.20 (130.235.16.20) connect to service peterm initially as user peterm (uid = 503, gid = 20) (pid 78387)   # ...   # [12/13/2010 10:06:07, 1, pid = 78387] / SourceCache/samba/samba-235.5/samba/source/smbd/service.c: close_cnum (1289)   # 130.235.16.20 (130.235.16.20) closed connection to service peterm   # So divided in two lines!   for IP in $(lsof -i -n | grep EST | grep smbd | cut -d\> -f2 | cut -d: -f1)   do     grep -n "$IP\b" $SMB_loggfile | grep "connect to service" | tail -1 > /tmp/smb_slask     RAD="$(less /tmp/smb_slask  | cut -d: -f1)"     SMB_user="$(less /tmp/smb_slask  | awk '{print $11}')" #    SMB_from="$(less /tmp/smb_slask  | awk '{print $2}')"     SMB_from="$(less /tmp/smb_slask  | cut -d\( -f2 | cut -d\) -f1)"     IP="$SMB_from"     SMB_time="$(sed -n $(echo $(( $(echo $RAD) - 1 )))p /var/log/samba/log.smbd | cut -d, -f1 | cut -d\[ -f2)"     GetDNS     check_ip     Location=" ($Country, $City)"     echo " - mounted by \"$SMB_user\" from ${HOSTNAME%%.$DOMAIN}${Location%%$Localhost_Location} at $SMB_time${FieldSeparator}" >> "$SharingFile"     rm -f /tmp/smb_slask 2> /dev/null   done   ########################   # # Check FTP   ########################   FTP_Share="$(defaults read /var/db/launchd.db/com.apple.launchd/overrides com.apple.ftpd 2> /dev/null | grep [D]isabled | awk '{print $3}' | sed 's/;//g')"   FTP_Verification="$(lsof -i :20)"   #if [ "$FTP_Share" = "0" -a -n "$FTP_Verification" ]; then   if [ "$FTP_Share" = "0" ]; then     Share_FTP="t"   else     Share_FTP="f"   fi   echo "FTP${FieldSeparator}$(if [ "$Share_FTP" = "t" ]; then echo "ON"; else echo "OFF"; fi)" >> "$SharingFile"   # List of those who are logged   FTP_loggfile=/var/log/ftp.log   # Check the logs and report   # Typical logfile (login and logout) looks like this:   # December 20 16:32:03 paravel ftpd [67765]: Connection from 130.235.16.41 to 130.235.16.211   # December 20 16:32:08 paravel ftpd [67765]: FTP LOGIN FROM 130.235.16.41 as peterm (class: real, type: REAL)   # December 20 16:32:30 paravel ftpd [67765]: Data Traffic: 6552 bytes in 2 files   # December 20 16:32:30 paravel ftpd [67765]: Total traffic: 7623 bytes in 2 transfers   for FTP_pid in $(lsof -i -n | grep EST | grep ftpd | awk '{print $2}' | uniq)   do     grep -n "$FTP_pid" $FTP_loggfile | grep "LOGIN" > /tmp/ftp_slask     FTP_user="$(less /tmp/ftp_slask | cut -d\] -f2 | awk '{print $7}')"     IP="$(less /tmp/ftp_slask | cut -d\] -f2 | awk '{print $5}')"     FTP_time="$(less /tmp/ftp_slask | awk '{print $1" "$2" "$3}')"     GetDNS     check_ip     Location=" ($Country, $City)"     echo " - authenticated by \"$FTP_user\" from ${HOSTNAME%%.$DOMAIN}${Location%%$Localhost_Location} at $SMB_time${FieldSeparator}" >> "$SharingFile"     rm -f /tmp/ftp_slask 2> /dev/null   done   ########################   # # Check HTTP   ########################   HTTP_Share="$(defaults read /var/db/launchd.db/com.apple.launchd/overrides org.apache.httpd 2> /dev/null | grep [D]isabled | awk '{print $3}' | sed 's/;//g')"   HTTP_Verification="$(lsof -i :80)"   if [ "$HTTP_Share" = "0" -a -n "$HTTP_Verification" ]; then     Share_HTTP="t"   else     Share_HTTP="f"   fi   echo "Web-server (http)${FieldSeparator}$(if [ "$Share_HTTP" = "t" ]; then echo "ON"; else echo "OFF"; fi)" >> "$SharingFile"   ########################   ## Check SSH   ########################   SSH_Share="$(defaults read /var/db/launchd.db/com.apple.launchd/overrides com.openssh.sshd 2> /dev/null | grep [D]isabled | awk '{print $3}' | sed 's/;//g')"   SSH_Verification="$(lsof -i :22)"   if [ "$SSH_Share" = "0" -a -n "$SSH_Verification" ]; then     Share_SSH="t"   else     Share_SSH="f"   fi   echo "Secure shell${FieldSeparator}$(if [ "$Share_SSH" = "t" ]; then echo "ON"; else echo "OFF"; fi)" >> "$SharingFile"   # Rapportera ssh-inloggningar   SuccessfulSSH=/Library/com.any/Breakins/Successful_ssh.txt   if [ -f "$SuccessfulSSH" ]; then     exec 6<"$SuccessfulSSH"     while read -u 6 Month Day Time PID Way Who IP     # December 13 17:35:04 18 759 interactively peterm 130.235.16.20     do       # Is the user still logged in?       if [ "`ps -ef | grep [s]sh | grep -v "^    0 " | grep "\b$(echo $PID | sed 's/sshd\[//g' | sed 's/\]://g')\b"`" ]; then         # Determine hostname (a) for IP. Scale of the ending point         # This function gives: $ HOST         GetDNS         # Look up geolokationen         # This function gives: $ City, $ Country         check_ip         echo " - \"$Who\" logged in from ${HOSTNAME%%.$DOMAIN}${Location%%$Localhost_Location} at $Month $Day $Time${FieldSeparator}" >> "$SharingFile"       fi     done   fi   ########################   ## Check Printer Sharing   ########################   #SMB_Share="$(defaults read /var/db/launchd.db/com.apple.launchd/overrides org.samba.nmbd 2> /dev/null | grep [D]isabled | awk '{print $3}' | sed 's/;//g')"   Print_Share="$(grep "enable print services" /var/db/smb.conf | cut -d= -f2 | sed 's/^\ *//g')"   Print_Verification_139="$(lsof -i :139)"   Print_Verification_445="$(lsof -i :445)"   if [ "$Print_Share" = "yes" -a -n "$Print_Verification_139" -a -n "$Print_Verification_445" ]; then     Share_Print="t"   else     Share_Print="f"   fi   echo "Printer-sharing${FieldSeparator}$(if [ "$Share_Print" = "t" ]; then echo "ON"; else echo "OFF"; fi)" >> "$SharingFile"   ########################   ## Check ARD   ########################   ARD_Share="$(defaults read /var/db/launchd.db/com.apple.launchd/overrides com.openssh.sshd 2> /dev/null | grep [D]isabled | awk '{print $3}' | sed 's/;//g')"   ARD_Verification_5900="$(lsof -i :5900)"   ARD_Verification_3283="$(lsof -i :3283)"   if [ "$ARD_Share" = "0" -a -n "$ARD_Verification_5900" -a -n "$ARD_Verification_3283" ]; then     Share_ARD="t"   else     Share_ARD="f"   fi   VNC="$(defaults read /Library/Preferences/com.apple.RemoteManagement VNCLegacyConnectionsEnabled)"   echo "Apple Remote Desktop${FieldSeparator}$(if [ "$Share_ARD" = "t" ]; then echo "ON"; else echo "OFF"; fi)" >> "$SharingFile"   # List of those who are logged   ARD_loggfile=/var/log/appfirewall.log   # Check the logs and report   # Typical logfile (only login - logout visible only through the process is over) looks like this:   # December 20 paravel 16:34:20 Firewall [76]: Allow AppleVNCServer connecting from 130.235.225.135:50940 to port 5900 proto = 6   # The name of the user authenticate themselves visible only by seeing who owns the process!   for IP in $(lsof -i -n | grep EST | grep AppleVNCS | cut -d\> -f2 | cut -d\] -f1 | cut -d\[ -f2 | sed 's/:*//g')   do     grep "$IP:" $ARD_loggfile | grep "Allow AppleVNCServer connecting from $IP" | tail -1 > /tmp/ard_slask     ARD_user="$(lsof -i -n | grep EST | grep AppleVNCS | grep "$IP" | awk '{print $3}')"     ARD_time="$(less /tmp/ard_slask | awk '{print $1" "$2" "$3}')"     GetDNS     check_ip     Location=" ($Country, $City)"     echo " - accessed by \"$ARD_user\" from ${HOSTNAME%%.$DOMAIN}${Location%%$Localhost_Location} at $ARD_time${FieldSeparator}" >> "$SharingFile"     rm -f /tmp/ard_slask 2> /dev/null   done   echo "VNC${FieldSeparator}$(if [ "$VNC" = "1" ]; then echo "ON"; else echo "OFF"; fi)" >> "$SharingFile"     ########################   ## Check Internet Sharing   ########################   Internet_Share="$(defaults read /var/db/launchd.db/com.apple.launchd/overrides com.apple.InternetSharing 2> /dev/null | grep [D]isabled | awk '{print $3}' | sed 's/;//g')"   Internet_Verification="$(lsof -i :53)"   if [ "$Internet_Share" = "0" -a -n "$Internet_Verification" ]; then     Share_Internet="t"   else     Share_Internet="f"   fi   echo "Internet-sharing${FieldSeparator}$(if [ "$Share_Internet" = "t" ]; then echo "ON"; else echo "OFF"; fi)" >> "$SharingFile"   ########################   ## Check RemoteAppleEvents   ########################   RAE_Share="$(defaults read /var/db/launchd.db/com.apple.launchd/overrides com.apple.AEServer 2> /dev/null | grep [D]isabled | awk '{print $3}' | sed 's/;//g')"   RAE_Verification="$(lsof -i :3031)"   if [ "$RAE_Share" = "0" -a -n "$RAE_Verification" ]; then     RAE_Internet="t"   else     RAE_Internet="f"   fi   echo "Remote Apple Events${FieldSeparator}$(if [ "$RAE_Internet" = "t" ]; then echo "ON"; else echo "OFF"; fi)" >> "$SharingFile"   ########################   ## Check Xgrid   ########################   Xgrid_Share="$(defaults read /var/db/launchd.db/com.apple.launchd/overrides com.apple.xgridagentd 2> /dev/null | grep [D]isabled | awk '{print $3}' | sed 's/;//g')"   if [ "$Xgrid_Share" = "0" ]; then     Xgrid_Internet="t"   else     Xgrid_Internet="f"   fi   echo "Xgrid${FieldSeparator}$(if [ "$Xgrid_Internet" = "t" ]; then echo "ON"; else echo "OFF"; fi)" >> "$SharingFile"  exit 0 fi # # <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # Print! IFS=_ exec 5<"$SharingFile" if [ -s "$SharingFile" ]; then   DATE=$(ls -ls "$SharingFile" | awk '{ print $7" "$8" "$9 }')   printf "${ESC}1;40;37mFile-sharing status:$Reset ${ESC}47;30m($DATE)${Reset}\n\n" #  printf "\n\n${ESC}${BoldFace}mStatus of File Sharing:$Reset ($DATE)\n\n"   printf "${ESC}${UnderlineFace};${YellowFont}m$Formatstring$Reset\n" "Sharing" "Status" fi while read -u 5 Share Status do   if [ "$Status" = "ON" -o -z "$Status" ]; then     FontColor="$WhiteFont"   else     FontColor="$RedFont"   fi   if [ "$(echo $Share | cut -c1-2)" = " -" ]; then     printf "${ESC}${BGColor};${ItalicFace};${FontColor}m$Formatstring$Reset\n" "$Share" "$Status"   else     printf "${ESC}${BGColor};${FontColor}m$Formatstring$Reset\n" "$Share" "$Status"   fi done # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ exit 0 ~~~ 如果需要定时运行,将下面文件存放在/Library/LaunchDaemons/com.any.plist,之后 launchctl load /Library/LaunchDaemons/com.any.com.plist launchctl start com.any.com.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>Label</key> <string>se.lth.cs.logger</string> <key>ProgramArguments</key> <array> <string>/usr/bin/logger.sh</string> </array> <key>StartInterval</key> <integer>300</integer> </dict> </plist> ~~~ Tony Liu, July 2011 Tony Liu - Http://cs.lth.se/kontakt/peter_moller/script/loggersh/Tony Liu - http://cs.lth.se/kontakt/peter_moller/script/
';

OS X: 实用脚本程序(bash scripts)系列-13

最后更新于:2022-04-01 10:56:58

在远程电脑上启动ssh并端口在3211 把下面的脚本保存,并在目标机运行后,在本机输入ssh user@targetmachine -p 3211就可以了 ~~~ #!/bin/bash if ( ! "$USER = "root" ); then echo "run it as root" exit 1 fi echo "<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Disabled</key> <false/> <key>Label</key> <string>local.sshd</string> <key>Program</key> <string>/usr/libexec/sshd-keygen-wrapper</string> <key>ProgramArguments</key> <array> <string>/usr/sbin/sshd</string> <string>-i</string> </array> <key>Sockets</key> <dict> <key>Listeners</key> <dict> <key>SockServiceName</key> <string>avsecuremgmt</string> </dict> </dict> <key>inetdCompatibility</key> <dict> <key>Wait</key> <false/> </dict> <key>StandardErrorPath</key> <string>/dev/null</string> <key>SHAuthorizationRight</key> <string>system.preferences</string> </dict> </plist> " > /Library/LaunchDaemons/ssh-3211.plist launchctl load /Library/LaunchDaemons/ssh-3211.plist exit 0 ~~~
';

OSX:隐藏文件或文件夹

最后更新于:2022-04-01 10:56:56

编者注:用了这几天的时间终于完成了这个小实用程序的工作,包括xcode的编写调制,google开放项目,大致的文档编写。终于可以发布了! ### 简单介绍: 这个软件是基于GNU GPL v3开放软件协议的项目,它的项目叫[HideMe4Mac](http://code.google.com/p/hideme4mac), 官方网址是:[http://code.google.com/p/hideme4mac](http://code.google.com/p/hideme4mac). 这个实用工具的初衷是这样的:用户可能需要把一些文件或者目录隐藏起来,不让它们在Mac OS X系统的Finder中显示,这样起到一定的安全保密作用。以前,普通用户需要使用脚本进行这些操作,对于不太了解或者没有脚本使用经验的用户来说,对这个操作有些恐惧,那么这个小工具就是为这些用户开发的。 它的节本功能是,隐藏用户指定的文件或者文件夹,并建立一个替身文件,便于用户存取。 ### 基本使用 > 他的使用相当的简单。当你运行该程序的时候,首先看到的是下面这个窗口。 > #### ![主画面](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-19_57158f5160329.gif) > 1. 设定隐藏文件: “隐藏文件”输入框中,存放的是需要被隐藏的文件的全目录文件名/文件夹名。你可以选择手动输入;已可以先找到该文件/文件夹,从Finder里拖到并放置在这里;或者使用它旁边的按钮开启文件管理窗口,来选择该文件,点击鼠标选中它,然后点击Open按钮。 > 1. 设定替身文件: “替身名称”输入框中,存放的是便于你存取该隐藏文件的替身文件名,如果你没有指定它,并且你是通过文件管理窗口设定隐藏文件的,那么系统会自动为你选择一个替身文件名,该文件默认地在当前用户的桌面上,名称和隐藏文件同名。 > 1. 隐藏: 点击“隐藏”按钮,系统会把隐藏文件隐藏,并创建一个替身文件。 > 1. 显示: 你还可以把原来隐藏了的文件恢复显示状态,只要按“显示”按钮,就可以了。 > #### ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-19_57158f5175c32.gif) ### 下载安装 > 请到官方的开源项目网站[http://code.google.com/p/hideme4mac](http://code.google.com/p/hideme4mac),下载该软件。 > 它的安装也简单,就是先鼠标双击该下载的Hideme.dmg文件,系统会把它装载到系统中,在桌面上找到HideMe,将里面的HideMe.app程序拖动到Applications里面,或者任何你认为方便的地方。 ### 常见问题 1. **为什么信息栏里面显示的是英文?** 回答: 信息栏帮助用户和软件开发人员排错,完全不影响用户的正常使用。如果有错误,把里面的信息复制并报告。 1. **文件没有被隐藏.** 回答:当前用户必须对该文件有写权限,现在的版本不支持管理员用户认证。 1. **替身文件无法建立.** 回答: 如果替身文件名已经存在,或者用户对该替身文件所在的文件夹没有写权限,都有可能发生这样的问题。 ** ** 1. **如果替身没有建立,文件也被隐藏了呢?** 回答:用户遇到这样的情况时,最好的方法是,按“显示”按钮,这样就会看见被隐藏的文件了。 1. **怎么删除替身文件?** 回答:建议普通用户,首先把隐藏文件显示后,手动将替身文件拖动到废纸篓。 ** ** 1. **还有问题?** 回答:请到项目官方网站寻求解答。 ### 资源: 这个软件是基于GNU GPL v3开放软件协议的,而且它的官方网站是[http://code.google.com/p/hideme4mac](http://code.google.com/p/hideme4mac)。你如果希望添加功能,软件改进等,可以通过不同的方式参与:你可以到该网站检查是否有软件更新;或者在他的官方网站发问题;如果你希望改进画面,跟我联系;如果你是程序员,可以把自己的改进传给我,或者加入到该项目中成为committers或者contributors等等。这些参与方式都是对该项目的支持,请你根据自己的实际情况选择适合自己的方式参与进来。 Tony Liu, 2011
';

OSX: Finder的侧边栏(Sidebar)不显示已装载的网络共享

最后更新于:2022-04-01 10:56:54

注:下面将混用Sidebar和cebianlan       在以前的10.5的豹子系统中,当用户,无论是通过什么方式,GUI还是命令行,把网络共享装载后(mount),它可以显示在用户的Desktop上,还会在Finder的侧边栏中自动显示,这个方式在企业环境中,方便用户直接访问网络共享,在任何的软件中存取文件。而在10.6的雪豹中,这种默认的行为被改变了,也就是,不自动地显示在侧边栏中了。       对于一般用户,从侧边栏中访问网络已经装载的网络共享,是非常方便的。对于企业环境中,网络管理员通过各种方式可以为用户在登录后自动装载网络共享,但是如果不在Finder的侧边栏中显示,用户会感到不便,重要的是,在雪豹中没有提供可以选择的GUI设置来建立这个自动方式。       在10.6系统,为了可以让它显示在侧边栏中,可以有几种选择。       一种是用户行为:也就是客户首先打开Finder窗口,把装载了的网络共享拖动到侧边栏中,这样系统会记住用户的选择,在下次装载同一个网络共享后,会自动将它显示在侧边栏中。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-19_57158f514137e.gif)       一种是管理员行为:通过下面的步骤,管理员可以轻松的管理。 > 首先,Sidebar的行为都是在每个用户的配置文件~/Library/Preferences/com.apple.sidebarlists.plist设定管理的。 > 然后在该Plist文件中,确认systemitems里面的ShowServers值是True. 再确认每个网络共享的行为一个设置值,在systemitems->VolumeList数组中,每个数组成员都是一个dictionary结构,在其中找到该网络共享的名称,也就是该dictionary中的Name值,添加或者变更Visibility的值为"AlwaysVisible",这样它就会在侧边栏显示了。如果希望禁止显示,那么可以设定为:NeverVisible。       管理员可以首先在一个测试机上,把这个网络共享的dictionary复制下来,然后使用MCX来实施用户管理。 Tony Liu, July 2011
';

OS X Lion狮子的恢复盘的删除二法

最后更新于:2022-04-01 10:56:52

注意:没有经验的轻不要尝试,或者找有经验的技术人员帮助,下面的操作可能导致硬盘数据的丢失! 这个650MB的恢复盘,目前来说没有任何用处,它需要你从App Store下载才能重新安装Lion系统,至少对于我们使用ESD光盘方式安装的来说,完全没有用处,所以释放它的空间给Lion分区吧 首先查看当前系统的分区状况: 命令:diskutil list 我的系统显示如下: ~~~ /dev/disk0 #: TYPE NAME SIZE IDENTIFIER 0: GUID_partition_scheme *200.0 GB disk0 1: EFI 209.7 MB disk0s1 2: Apple_HFS MyHD 199.7 GB disk0s2 /dev/disk1 #: TYPE NAME SIZE IDENTIFIER 0: GUID_partition_scheme *120.0 GB disk1 1: EFI 209.7 MB disk1s1 2: Apple_HFS Server 68.7 GB disk1s2 3: Apple_HFS Data 42.6 GB disk1s3 4: Apple_Boot Recovery HD 654.6 MB disk1s4 5: Apple_HFS Mac OS X Install ESD 7.6 GB disk1s5 ~~~ 方法一: 我的Lion安装到了Data里面,可以看到,Recovery HD是在我的Data的下面。 使用下面命令来合并两个分区。 ~~~ diskutil mergePartitions HFS+ Data disk1s3 disk1s4 ~~~ 上面的命令使用中,一定把disk1s3 disk1s4换成你的系统的相应的值。 需要注意的是,安装Lion的分区一定要是Journaled HFS+,否则Lion分区的数据会被删除! 还有一个更图形化的方法: 在找到Recovery HD之后,使用下面命令来删除它先: ~~~ diskutil eraseVolume HFS+ Blank /dev/disk1s4 ~~~ 之后你可以看见在桌面上出现Blank,之后使用Disk Utility来实现两个分区的合并,这样更加保险一点。
';

OS X Lion狮子安装盘的初步研究

最后更新于:2022-04-01 10:56:49

狮子的安装会自动在硬盘中生成一个650MB的恢复盘分区,这个分区在正常的GUI界面中是看不见的。使用下面的语句可以看见硬盘的分区情况: diskutil list 这样可以看到这个隐藏的分区的名称是Recovery HD 使用命令来安装到GUI中(比如我的是disk1s4): diskutil mount disk1s4 进入后,下面是它的根里面的内容: d-wx-wx-wt@ 3 root  _unknown  hidden 102  2 Jul 22:52 .Trashes drwxr-xr-x@ 3 root  admin     -      102  2 Jul 16:16 .fseventsd -rw-r--r--@ 1 root  admin     -        0  2 Jul 16:16 .metadata_never_index drwxr-xr-x@ 9 root  admin     -      306  2 Jul 16:17 com.apple.recovery.boot 在com.apple.recovery.boot目录里面的内容: total 930040 drwxr-xr-x@ 9 root  admin        306  2 Jul 16:17 . drwxrwxr-x  8 root  admin        340  2 Jul 16:16 .. -rw-r--r--@ 1 root  admin        749  2 Jul 16:17 .disk_label -rw-r--r--@ 1 root  wheel  451307798  2 Jul 16:07 BaseSystem.dmg -rw-r--r--@ 1 root  wheel       2245 15 Jun 19:06 PlatformSupport.plist -r--r--r--@ 1 root  wheel        475 29 Jun 21:42 SystemVersion.plist -rw-r--r--@ 1 root  wheel     858800 30 Jun 00:04 boot.efi -rw-r--r--@ 1 root  admin        361  2 Jul 16:17 com.apple.Boot.plist -rw-r--r--@ 1 root  wheel   23992189 29 Jun 23:41 kernelcache 这里就是启动盘的所有内容了。 看看每个文件的内容: SystemVersion.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>ProductBuildVersion</key>     <string>11A511</string>     <key>ProductCopyright</key>     <string>1983-2011 Apple Inc.</string>     <key>ProductName</key>     <string>Mac OS X</string>     <key>ProductUserVisibleVersion</key>     <string>10.7</string>     <key>ProductVersion</key>     <string>10.7</string> </dict> </plist> PlatformSupport.plist 它和安装盘中的是一样的内容,里面是所支持的硬件主板id号列表 com.apple.Boot.plist :是控制如何使用这个BaseSystem.dmg文件来启动系统恢复程序的 <?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>Kernel Cache</key>     <string>\com.apple.recovery.boot\kernelcache</string>     <key>Kernel Flags</key>     <string>rp=file:///com.apple.recovery.boot/BaseSystem.dmg</string> </dict> </plist> 再将BaseSystem.dmg安装到GUI中,可以看到这个图 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-19_57158f50e2b62.gif) 就是一个核心系统,它自动运行Insall Mac OS X Lion.app程序,来恢复系统。不过这个恢复的过程需要从App Store下载安装的方式。 Install Mac OS X Lion.app运行的画面就是在安装过程中的画面: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-19_57158f51132f6.gif) 回头看看ESD安装盘的内容,上面的这些文件都可以在ESD安装盘上找到: total 960568 drwxrwxr-t  20 root      admin           748  2 Jul 15:48 . drwxrwxrwt@  9 root      admin           306  2 Jul 22:58 .. -rw-r--r--@  1 dd        admin         15364  2 Jul 23:17 .DS_Store drwx------   5 _unknown  _unknown        170  2 Jul 17:27 .Spotlight-V100 d-wx-wx-wt@  3 _unknown  _unknown        102  2 Jul 21:59 .Trashes -rwxr-xr-x@  1 root      wheel            82 13 Jun 12:47 ._Instructions.localized -rw-r--r--@  1 root      admin           581 30 Jun 00:55 .disk_label drwx------   6 _unknown  _unknown        204  2 Jul 17:53 .fseventsd -rw-r--r--@  1 root      admin          1876 30 Jun 00:55 BaseSystem.chunklist -rw-r--r--@  1 root      admin     451307798 30 Jun 00:47 BaseSystem.dmg drwxr-xr-x@  3 root      wheel           102 29 Jun 20:24 Install Mac OS X Lion.app drwxr-xr-x@  4 root      wheel           136  2 Jul 23:17 Library -r--r--r--@  1 root      wheel         46516  8 Jun  2010 MacOSX_Media_Background.png drwxr-xr-x@ 51 root      wheel          1734 30 Jun 00:55 Packages drwxr-xr-x@  3 root      wheel           102 16 Jun 17:07 System -rw-r--r--@  1 root      admin        858800 30 Jun 00:52 boot.efi -rw-r--r--@  1 root      admin      23992189 30 Jun 00:54 kernelcache -rw-r--r--@  1 root      wheel      15565140 18 Jun 13:59 mach_kernel drwxr-xr-x@  3 root      wheel           102 16 Jun 16:57 private drwxr-xr-x@  4 root      wheel           136 30 Jun 00:52 usr 对比一下10.6和10.7的boot.efi文件的大小: 10.6的Boot.efi文件大小是332464 bytes,而Lion的是858800 bytes. ESD中的com.apple.Boot.plist在/Library/Preferences/SystemConfiguration/里面 <?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>Kernel Flags</key>     <string>root-dmg=file:///BaseSystem.dmg</string>     <key>Kernel Cache</key>     <string>\kernelcache</string> </dict> </plist> 它和上面的恢复盘的内容有些差别,路径不一样,而且参数也不一样,一个是root-dmg一个是rp 另外,Lion增加了一个硬盘检测的程序叫做hwmond 安装盘的硬件检测部分: /System/Library/Launchdaemons/com.apple.hwmond.plist cat /Volumes/Mac\ OS\ X\ Install\ ESD/System/Library/LaunchDaemons/com.apple.hwmond.plist <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict>     <key>Label</key>     <string>com.apple.hwmond</string>     <key>OnDemand</key>     <false/>     <key>Program</key>     <string>/usr/sbin/hwmond</string>     <key>ProgramArguments</key>     <array>         <string>hwmond</string>     </array>     <key>ServiceIPC</key>     <false/> </dict> </plist> 它的硬件测试返回代码:/Volumes/Mac\ OS\ X\ Install\ ESD/private/etc/hwmond.SMART 通过比较安装盘和恢复盘的两个Install Mac OS X Lion.app是完全一样的. 这个BaswSystem.dmg对于管理环境中的系统恢复会是比较有用的。
';

狮子GM版本的安装

最后更新于:2022-04-01 10:56:47

这是网上传说的OS X Lion的GM版本,下面是升级安装的过程,是从Lion Preview 4升级的。 首先是找到安装影像文件:根据下面三个图的步骤找到这个DMG文件,并把它还原到一个用于安装的盘上。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-19_57158f4f9b111.gif) ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-19_57158f4fb1a25.gif) ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-19_57158f4fd2c53.gif) 之后是重新启动,并按住Option键,以选择启动分区,也就是上面恢复的分区盘。(后面的都是屏幕照片可能不太清楚) ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-19_57158f5003bcb.gif) 这是启动后的安装界面,这个界面于以前的比较,不常用的工具和选项放在了明显的注画面中,而其它的三个工具还是放在菜单栏中的菜单中。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-19_57158f501cb85.gif) ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-19_57158f50332a0.gif) 下面这一步,纯粹是多余,完全可以被舍弃。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-19_57158f504ef36.gif) 这一步依然是继承了苹果系统的传统,需要两次确认同意改协议 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-19_57158f5075f2c.gif) 现在是选择安装的目标盘。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-19_57158f508eb83.gif) 之后就是安装过程。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-19_57158f50a32a3.gif) ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-19_57158f50c5f46.gif) 由于上传图片太多,所以之后再写一篇([OSX Lion狮子GM版本的安装(续)](http://blog.csdn.net/afatgoat/article/details/6581633))
';

OSX脚本:禁止系统自动添加AppStore图标到用户Dock上

最后更新于:2022-04-01 10:56:45

这个脚本会删除Dock程序默认的自动添加App Store.app图标到用户Dock上的行为。 具体的操作使用参见脚本说明。   #!/bin/bash# ------------------------------------------------------------------------# Removing App Store icon from User's Dock:## Script name: RmAppStoreIcon.sh## Copy Right:# Copy Right 2011 Tony Liu, all right reserved.## Description:# If you don't want end user to have App Store icon on their Dock, this is right for you.# Why bother this? because most enterprise environment policies don't like people purchasing# stuff online, ie App Store.## The system wide Dock icon is stored in the plist file:# /System/Library/CoreServices/Dock.app/Contents/Resources/English.lproj/default.plist## This script needs PlistBuddy command line tools installed on your OS, which is included in most# of Apple packages. it's easy to be found anyway. Or pack commands in a installation package.## You can use the following command to remove it:# plistbuddy -c "delete :persistent-apps:0" /System/Library/CoreServices/Dock.app/Contents/Resources/English.lproj/default.plist## For newly login users, Dock.app will put the App Store icon on user's Dock automatically.# For logged in users, the App Store icon is already sits on their Dock.# To remove for all users, a the best practise example likes this:# removeSysAppStoreIcon# removeAllUserAppStoreIcon## Another approch: removing the "App Store.app" from /Applications folder totally.## For some situation, you may want end users to use it at home, but not in enterprise environment.# do the restriction within MCX or Workgroup Manager.## History:# Initial: Tony 2011-06-20## ------------------------------------------------------------------------# How to use these commands:# call removeAllUserAppStoreIcon to remove for all users# call removeUserAppStoreIcon USERNAME, to remove USERNAME user's App Store icon.# call removeSysAppStoreIcon to remove from system wide.# ------------------------------------------------------------------------function RemoveAppStore{ defaultPlist="$1" #currentSet=`plistbuddy -c "print :persistent-apps" $defaultPlist` #currentSet=${currentSet/////":"} index=0 while [ true ] do curAppIcon=`plistbuddy -c "print :persistent-apps:$index" $defaultPlist` echo "$index" "$curAppIcon" if [ -n "$curAppIcon" ]; then isAppStore=`echo $curAppIcon | grep "App Store"` if [ -n "$isAppStore" ]; then sudo plistbuddy -c "delete :persistent-apps:$index" $defaultPlist echo "Deleted App Store @ $index" break else let index=index+1 fi else break fi done}function removeSysAppStoreIcon{ RemoveAppStore "/System/Library/CoreServices/Dock.app/Contents/Resources/English.lproj/default.plist"}function removeUserAppStoreIcon{ RemoveAppStore "/Users/$1/Library/Preferences/com.apple.Dock.plist"}function removeAllUserAppStoreIcon{ for aUser in `ls -1 /Users` do removeUserAppStoreIcon "$aUser" done}RemoveAppStore "/Users/schooladmin/Desktop/default.plist"exit 0   Tony liu, June 2011 Calgary
';

OSX: 禁止Flash Player 10.3自动更新

最后更新于:2022-04-01 10:56:42

很简单,只要在/Library/Application Support/Macromedia/中生成文件mms.cg文件,并设置AutoUpdateDisable=1 或者使用如下命令行: mkdir -p /Library/Application/ Support/Macromediaecho "AutoUpdateDisable=1" > /Library/Application/ Support/Macromedia/mms.cfg
';

Mac OS X: 是否升级到Lion?

最后更新于:2022-04-01 10:56:40

在考虑升级到Lion之前,不仅要参考Apple官方发布的Lion支持的硬件平台的参数以及它的新颖特性(参见:[Mac OS X Lion:狮子来了](http://blog.csdn.net/afatgoat/archive/2011/06/07/6528855.aspx)),软件方面的兼容性也是一个重要方面。因为Lion已经放弃支持Rosetta了。Rosetta作为苹果由PPC硬件平台转向Intel平台的一个成功的工具,它使得用户可以使用旧的基于PPC的编码软件运行在Intel平台的新电脑上,这样为大家提供了最大的兼容性,随着从10.4直到10.6都是如此,但是Lion放弃了这个折中方案,也许苹果认为已经“仁至义尽”了。如果你的日常使用中,依赖一些软件,那么在升级前,一定要查 看现在的版本是否是PPC编码的,如果是,那么你肯定无法在新系统中使用它,是否升级的决定就要基于,是否由其它软件代替,你是否愿意投资升级等。另外,即便编码方式支持,某些软件在新系统中可能依然会出现或大或小的问题,这要仔细查看各个软件的兼容列表更新。目前 各个软件开发商肯定在预发布版本中测试自己的软件兼容性,相信在正式版发布不久,就会有各个软件的官方发布。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-19_57158f4f34ac0.gif) 在次之前,我们自己不妨先检查一番,做到心中有数。查看软件的编码方式,最常用的方法有一下几种: - 最简单的就是在Finder中,选中一个应用程序,使用Get Info来查看了。如果是Universal或者Intel,那么就可以,如果是PowerPC的就不行。 - 另外那可以使用System Profiler查看。在About This Mac中选择More Info...,在System Profiler窗口左边,选择Software分类下面的Software。根据你的软件的多少,系统可能会需要若干分钟,把当前系统中所有的软件列表于右方,见图,可以在Kind列中找到该软件的编码方式。这个方法比较全面,可以把系统中的所有软件一网打尽。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-19_57158f4f66f61.gif) - 还可以在Activity Monitor中找到系统那个正在运行的软件的编码,见图 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-19_57158f4f66f61.gif) 其实,当新系统刚刚正式发布的时候,对于普通用户,真的没有必要立刻更新,每个人还是根据自己的需求做好准备,另外10.6的技术支持还会持续一段时间的。        
';

Mac OS X:显示/设置分辨率的命令(源程序)

最后更新于:2022-04-01 10:56:38

注:把变更现实分辨率的代码完成了。 变更的时候,因为10.6不再提供诸如10.5之前的设置最佳分辨率的系统功能,所以需要自己编写。   设置和显示显示分辨率-源码 下面是一个设置和显示当前系统显示设备和分辨率的源码 如果有兴趣,大家给测试一下各自的环境下,它工作的情况。 几个概念: Display: 每个当前连接到系统中的显示器 Main Display: 当前的主显示设备 Mode: 是每个显示设备和系统之间连接后,系统自动生成的管理它的一个内存对象,分辨率是其中的一个部分,每个显示设备可能有好多mode,这些mode组成一个列表。 编译步骤:    首先要安装了xcode开发环境,把下面的源码复制到一个文本编辑器中,比如TextEdit,然后使用文本方式保存,比如该源码的文件命是screenresolution.m,保存在你的Desktop上。再编译:在Terminal里面输入命令: cd ~/Desktopc++ screenresolution.m -framework ApplicationServices -o screenresolution -arch i386 这样就在你的Desktop上生成了一个交screenresolution的程序. 具体使用,在Termianl里面运行: - 获得帮助:~/Desktop/screenresolution -h - 获得当前显示器的个数:~/Desktop/screenresolution -a - 当前主显示器的分辨率:~/Desktop/screenresolution - 获得当前第2个显示器的分辨率:~/Desktop/screenresolution 2 - 获得主显示器支持的分辨率列表:~/Desktop/screenresolution -l - 获得第2个显示器支持的分辨率列表:~/Desktop/screenresolution -l 2 - 设置当前主显示器的分辨率为800x600:~/Desktop/screenresolution -s 800 600 - 设置第2个显示器的分辨率为800x600:~/Desktop/screenresolution -s 2 800 600 注意: 这个版本是为OS X 10.6以上版本做的. 在10.6系统上编译成功并运行成功;没有在10.5上编译过;10.6编译成功的执行命令,也没有在10.5系统上运行过-应该是无法运行的-谁有条件给测试一下。因为10.6把好多10.5里面的底层函数都改了。 已知的:   - 没有考虑两个显示器mirro的状态 - 设置分辨率尽量使用系统列出的所支持的分辨率,否则设置可能不成功。 其它的: - 测试过的给个回信。 - 希望新功能的, 请说 - 这个程序主要是用来控制远程电脑的分辨率。 源代码   /* * screenresolution.m * * Description: * It set/get current Online display resolutions. * * The version on webpage http://forums.macosxhints.com/showthread.php?t=59575 * is before 10.6. This is for 10.6 and more functions. * * Author: * Tony Liu, June 2011 * * Version History: * 2011-06-01: add -a option. * 2011-06-08: Display adding flags and not display duplicate modes. * 2011-06-09: Adding set the best fit resolution function. * * COMPILE: * c++ screenresolution.m -framework ApplicationServices -o screenresolution -arch i386 * */#include <ApplicationServices/ApplicationServices.h>struct sLIST { double width, height; CGDisplayModeRef mode;};typedef int (*compfn)(const void*, const void*);void ListDisplays(uint32_t displayTotal);void ListDisplayAllMode (CGDirectDisplayID displayID, int index);void PrintUsage(const char *argv[]);void PrintModeParms (double width, double height, double depth, double freq, int flag);int GetModeParms (CGDisplayModeRef mode, double *width, double *height, double *depth, double *freq, int *flag);int GetDisplayParms(CGDirectDisplayID disp, double *width, double *height, double *depth, double *freq, int *flag);bool GetBestDisplayMod(CGDirectDisplayID display, double dwidth, double dheight);int modecompare(struct sLIST *elem1, struct sLIST *elem2);uint32_t maxDisplays = 20;CGDirectDisplayID onlineDisplayIDs[20];uint32_t displayTotal;char *sysFlags[]={"Unknown","Interlaced,", "Multi-Display,", "Not preset,", "Stretched,"};char flagString[200];int main (int argc, const char * argv[]){ double width, height, depth, freq; int flag; int displayNum; CGDirectDisplayID theDisplay; // 1. Getting system info. if (CGGetOnlineDisplayList (maxDisplays, onlineDisplayIDs, &displayTotal) != kCGErrorSuccess) { printf("Error on getting online display List."); return -1; } if (argc == 1) { CGRect screenFrame = CGDisplayBounds(kCGDirectMainDisplay); CGSize screenSize = screenFrame.size; printf("%.0f %.0f/n", screenSize.width, screenSize.height); return 0; } if (! strcmp(argv[1],"-l")) { if (argc == 2) { ListDisplays(displayTotal); return 0; } else if (argc == 3) { displayNum = atoi(argv[2]); if (displayNum <= displayTotal && displayNum > 0) { ListDisplayAllMode (onlineDisplayIDs[displayNum-1], 0); } } return 0; } if (! strcmp(argv[1],"-a")) { printf("Total online displays: %d/n", displayTotal); return 0; } if ((! strcmp(argv[1],"-?")) || (! strcmp(argv[1],"-h"))) { PrintUsage(argv); return 0; } if (! strcmp(argv[1],"-s")) { if (argc == 4) { displayNum = 1; width = atoi(argv[2]); height = atoi(argv[3]); } else if (argc == 5) { displayNum = atoi(argv[2]); width = atoi(argv[3]); height = atoi(argv[4]); } if (displayNum <= displayTotal) flag = GetBestDisplayMod(displayNum-1, width, height); return flag; } displayNum = atoi(argv[1]); if (displayNum <= displayTotal) { GetDisplayParms(onlineDisplayIDs[displayNum-1], &width, &height, &depth, &freq, &flag); PrintModeParms (width, height, depth, freq, flag); return 0; } else { fprintf(stderr, "ERROR: display number out of bounds; displays on this mac: %d./n", displayTotal); return -1; } return 0;}void ListDisplays(uint32_t displayTotal){ uint32_t i; CGDisplayModeRef mode; double width, height, depth, freq; int flag; // CGDirectDisplayID mainDisplay = CGMainDisplayID(); printf("Total Online Displays: %d/n", displayTotal); for (i = 0 ; i < displayTotal ; i++ ) { printf (" Display %d (id %d): ", i+1, onlineDisplayIDs[i]); GetDisplayParms(onlineDisplayIDs[i], &width, &height, &depth, &freq, &flag); if ( i = 0 ) printf(" (main) "); PrintModeParms (width, height, depth, freq, flag); }}void ListDisplayAllMode (CGDirectDisplayID displayID, int iNum){ CFArrayRef modeList; CGDisplayModeRef mode; CFIndex index, count; double width, height, depth, freq; int flag; double width1, height1, depth1, freq1; int flag1; modeList = CGDisplayCopyAllDisplayModes (displayID, NULL); if (modeList == NULL) return; count = CFArrayGetCount (modeList); width1=0; height1=0; depth1=0; freq1=0; flag1=0; if (iNum <= 0) { for (index = 0; index < count; index++) { mode = (CGDisplayModeRef)CFArrayGetValueAtIndex (modeList, index); GetModeParms(mode, &width, &height, &depth, &freq, &flag); PrintModeParms (width, height, depth, freq, flag); } } } else if (iNum <= count) { mode = (CGDisplayModeRef)CFArrayGetValueAtIndex (modeList, iNum-1); GetModeParms(mode, &width, &height, &depth, &freq, &flag); PrintModeParms (width, height, depth, freq, flag); } CFRelease(modeList);}void PrintModeParms (double width, double height, double depth, double freq, int flag){ printf ("%ld x %ld x %ld @ %ld Hz, <%d>/n", (long int)width, (long int)height, (long int)depth, (long int)freq, flag);}int GetDisplayParms(CGDirectDisplayID disp, double *width, double *height, double *depth, double *freq, int *flag){ int iReturn=0; CGDisplayModeRef Mode = CGDisplayCopyDisplayMode(disp); iReturn = GetModeParms (Mode, width, height, depth, freq, flag); CGDisplayModeRelease (Mode); return iReturn;}int GetModeParms (CGDisplayModeRef Mode, double *width, double *height, double *depth, double *freq, int *sflag){ *width = CGDisplayModeGetWidth (Mode); *height = CGDisplayModeGetHeight (Mode); *freq = CGDisplayModeGetRefreshRate (Mode); CFStringRef pixelEncoding = CGDisplayModeCopyPixelEncoding (Mode); *depth = 0; if (pixelEncoding = NULL) return -1; if (pixelEncoding = CFSTR(IO32BitDirectPixels)) *depth = 32; else if (pixelEncoding = CFSTR(IO16BitDirectPixels)) *depth = 16; else *depth = 8; *sflag = CGDisplayModeGetIOFlags(Mode); CFRelease(pixelEncoding); return 0;}bool GetBestDisplayMod(CGDirectDisplayID display, double dwidth, double dheight){ CFArrayRef modeList; CGDisplayModeRef mode; CFIndex index, count, sindex, scount=0; double width, height, depth, freq; double width1, height1, depth1, freq1; int flag, flag1; struct sLIST mList[100]; int ireturn=0; modeList = CGDisplayCopyAllDisplayModes (display, NULL); if (modeList == NULL) return; count = CFArrayGetCount (modeList); scount=0; for (index = 0; index < count; index++) { mode = (CGDisplayModeRef)CFArrayGetValueAtIndex (modeList, index); GetModeParms(mode, &width, &height, &depth, &freq, &flag); // printf("........ scount=%d/n", (int)scount); if (!((width==width1) && (height==height1) && (depth==depth1) && (freq==freq1) && (flag==flag1))) { if (CGDisplayModeIsUsableForDesktopGUI(mode)) { mList[scount].mode=mode; mList[scount].width=width; mList[scount].height=height; width1=width; height1=height; depth1=depth; freq1=freq; flag1=flag; scount++; } } } mode=NULL; qsort ((void *) mList, scount, sizeof(struct sLIST), (compfn) modecompare); for (index=0; index<scount; index++) { if (mList[index].width >= dwidth) { if (mList[index].height >= dheight) { mode = mList[index].mode; break; } } } CGDisplayConfigRef pConfigRef; CGConfigureOption option=kCGConfigurePermanently; if ((mode != NULL) && (CGBeginDisplayConfiguration(&pConfigRef) == kCGErrorSuccess)) { CGConfigureDisplayWithDisplayMode(pConfigRef, display, mode, NULL); if (CGCompleteDisplayConfiguration (pConfigRef, option) !=kCGErrorSuccess) CGCancelDisplayConfiguration (pConfigRef); } else ireturn = -1; CFRelease(modeList); return ireturn;}int modecompare(struct sLIST *elem1, struct sLIST *elem2){ if ( elem1->width < elem2->width) return -1; else if (elem1->width > elem2->width) return 1; if (elem1->height < elem2->height) return -1; else if (elem1->height > elem2->height) return 1; else return 0;}void PrintUsage(const char *argv[]){ char *fname = strrchr(argv[0], '/')+1; printf("Screen Resolution v1.0, Mac OS X 10.6 or later, i386/n"); printf("Copyright 2010 Tony Liu. All rights reserved. June 1, 2010/n"); printf("/nUsage:"); printf(" %s -a/n", fname); printf(" %s [-l] [1..9]/n", fname); printf(" %s -s [ 1..9 ] hor_res vert_res/n", fname); printf(" %s -? | -h this help./n/n", fname); printf(" -l list resolution, depth and refresh rate/n"); printf(" 1..9 display # (default: main display)/n"); printf(" -l 1-9 List all support for the display #/n"); printf(" -s Set mode./n"); printf(" hor_res horizontal resolution/n"); printf("vert_res vertical resolution/n/n"); printf("Examples:/n"); printf("%s -a get online display number/n", fname); printf("%s get current main diplay resolution/n", fname); printf("%s 3 get current resolution of third display/n", fname); printf("%s -l get resolution, bit depth and refresh rate of all displays/n", fname); printf("%s -l 1 get first display all supported mode/n", fname); printf("%s -l 1 2 get first display the second supported mode/n", fname); printf("%s -s 800 600 set resolution of main display to 800x600/n", fname); printf("%s -s 2 800 600 set resolution of secondary display to 800x600/n", fname);}
';

Mac OS X:详细解读Munki和应用

最后更新于:2022-04-01 10:56:36

  blog注: 本文是一个简要版本   **详细****解****读Munki****及其****应****用****** 面对日益复杂的企业网络管理环境,一个小的工具,可能极大的方便系统管理员的企业日常维护需要,它可能不需要面面俱到,不一定需要付费,当然不需要美丽的外表包装,不过我们知道,需要热情和参与,包括你和我。 ### 综述: 在系统管理员的工作中,更新和维护客户系统是一项重要的任务,这是现代企业的基本要求。不久以前每个员工都可以在电脑上自己安装软件,这样带来了企业内部管理的混乱,随着内部管理的规范,普通员工被取消了任意安装软件的权限,这个任务由管理员承担,这样避免了很多外来病毒造成生产率降低的问题,这是系统管理员为什么要负责系统更新的原始冲动。 尤其是对于大型的企业环境,这种任务可以说是一种挑战,之所以这样说,不仅因为客户系统的维护基于客户原因等有着诸多的限制,而且巨大的工作站数量和各个部门需求的多样性,也是不可忽视的因素。随着企业对内部人员的权限管理的细致化的要求越来越高,系统管理员会承担更多的以前本可以客户自己完成的任务。比如一个重要的软件系统更新,需要及时部署到每个相关的客户系统上,由于各种原因,可能是客户在出差不在可以管理范围之内,或者是网络原因等,管理员不得不维护一个客户系统更新的列表,记录用户系统的现状,以及相继的问题解决方案等,当然现在有各种审计软件可供使用,但是依然需要管理员们主动的投入相当的热情,否则,客服可能就要接到一些莫名其妙的求救电话,使得各个部门之间的协调出现不必要的麻烦。当然了,如果可以投入精力把各个方面的人员都通知到,那么可能减少抱怨,但是工作量也会随之增加,而且人的记忆也是最不可靠的。不要忘了另外一点,各种各样的软件或者系统更新需求会一个接着一个的出现,不会停滞,否则系统管理员是否可以放长假了呢?维护这样一个复杂的环境,不仅需要审查系统,我们管理员更需要一种在符合现存企业规则的同时,尽量自动化的,避免跟踪个别客户状态的,或者可以描述为让客户承担起本属于自己的原始任务的策略。 在其它的系统环境中,有各自不同的解决方案,比如Windows用户就可以使用SMS和SCCM等,不过费用也是不少,第三方的免费方案也是有的。在 Mac系统环境中,以前的各种方案,侧重各有不同,现有的解决方案中比如CasperSuite, MacOS X Server, LANDesk Management Suite,Apple RemoteDesktop等等都是,他们功能各异,许可证费用来说相比较MS的更能让人接受。不过Mac系统也有好多免费软件。我们在这里介绍的是一种基于客户/服务器模型的一套工具, 这就是Munki。 总体来说,它的特点是:免费开源,简单有效,灵活强劲,最主要的是它可以让没有安装软件权限的客户,根据管理员灵活设定的框架,自动或者手动地安装所需的软件。之所以叫它是一套工具,而不是解决方案,主要是因为它的部署和实施的确需要管理员根据自己的网络 环境做相当的客户配置,需要变成,需要自己定制策略,然后确定实施范围和速度等等。但是它提供了一种基于软件的可能性。而且它还是处于一种发展阶段,需要完善和补充,结构和方向有了,基本的实现也有了,这其实给了我们极大的灵活性。它的突出特色是省却了管理员的更新维护工作中和客户直接打交道的费时工作,而是把这个任务部分地交给每个客户端和客户,客户端可以按计划自动检查更新并安装,并且不需管理员干预;用户也可以手动操作,并且给客户选择安装的自由。 有人问:这个和Mac系统提供的系统更新有什么区别?当然有区别,目前最显著的区别是,它不用管理员在客户机上的确认,就可以安装各种软件、补丁和升级等等,其实,它的功能不只这一点。 ### 谁是Munki? 它是一个开源的基于Python开发的适用于MacOS X系统(当前)的软件安装/更新管理的一套工具。目前是在Google上的一个开源项目,它的最初开发者是GregNeagle,创始者Greg原来是在另外一个苹果Google用户组的积极参与者,后来他把自己的开发项目公开了,最初的构思,受到radmind的极大影响(radmind是一个很早的Mac系统部署工具,也是免费开源的),现在发展成有20来个核心人员,人员不多,不过他们相当的活跃,使得这个项目进展得相当的稳健和迅速。这个项目也得到了Google开发团队的认可,Google自己的一个开源项目叫Simian就是基于这个项目之上的。 它的发音就是和猴子的英文monkey一样,所以中文就叫它猴子吧。这个名字没有特殊意义,有一种通过训练可以为人类提供特殊服务的猴子,开发者就想到了猴子这个名字。 ### 基本概念 在进一步了解它之前,先让我们来了解一下使用过程中我们会使用的概念。当然,这里没有说Mac系统部署过程中的普遍使用的概念,因为这里假定,你已经熟悉了这些基本概念。如果没有,或者参考其它资料,或者网上搜索,或者我们以后提及。 ### 货单(manifest): 其实在苹果系统管理里面,manifest的概念经常被用到。很简单,货单就是一种描述什么软件需要安装或者卸载等软件行为规则的文件,munki通过内部机制可以动态地指定某个或者某类电脑遵从某个货单定义的规则。默认的,它存放在服务器的manifest目录中。 ### 目录(catalog): 是描述在服务器上提供给用户可以使用的软件目录,是通过munki的内部命令来自动生成的,默认的,它存放在服务器的catalogs目录中。 ### 安装项目(pkgs): 是所有的软件安装包的总称,这是指具体的每个软件安装包,默认的,它们存放在服务器的pkgs目录中。 ### 包信息(pkgsinfo): 它是描述一个安装包详细信息的文件,它也是使用munki内部命令自动生成,当然管理员可以编辑它的内容,以符合自己的管理环境需要。默认的,存放在pkgsinfo目录中。 ### 客户/服务模型: 猴子是基于客户/服务器模型的,它对服务器端的要求相当的简单,就是一个Http服务器,我们叫它munki服务器;在客户端需要安装和正确配置munki,以便客户端能够正确地找到指定的服务器,并进行正确的操作。 ### 预执行代码(preflight): ### 后执行代码(postflight): 这两个概念同Mac安装包中的preflight和postflight脚本的概念是类似的,都是在执行正式步骤之前和之后需要做的事情。在munki里面他们特指在munki中的”受管软件更新”(ManagedSoftware Update)应用程序的。 ### 基本操作 ### 定制pkgs: 安装格式:** **猴子支持的安装程序包格式包括: ·     dmg格式:他可以支持直接复制应用程序到Applications目录操作,这种操作是好多简单程序采用的安装方式,简便直观。 ·     苹果支持的软件安装包:也就是单一文件的pkg包和mpkg包,以及包文件的pkg和mpkg安装包 ·     它还特定支持Adobe公司的使用 Adobe's Enterprise Deployment tools软件制作的CS3/CS4/CS5发布程序,以及它的更新包,还有从官方下载的Adobe Acrobat Pro 9.x更新程序包等。 #### 重新包装程序: 既然它支持这么多的程序安装包格式,每种格式适应语不同的软件需求,所以面对不同的程序,很多情况下需要管理员自己重新打包,重新打包的理由很多,可能是为了满足内部安全需求,或者是程序预先注册,或者是去掉一些功能,或者是提供方便的机制,或者添加各种判断脚本等等。 至于重新打包技术,在Mac系统上是管理员的基本技能之一,相关的软件也很多,无论是命令行的还是GUI的都有,而且免费的就很好用。比如:。 重新打包是软件安装升级成败的关键第一步,可能是管理员换费时间最多的一个步骤,不仅要反复测试,软件和硬件环境,而且要考虑周到,考虑到今后的升级卸载和软件许可的管理等等因素,所以管理员可能需要具备一定的编程能力,尤其是脚本书写能力。如果这部分都需要外包,那么就需要自我提高了。 ### 在服务器上登录造册 当我们有了需要部署到客户端的软件安装包之后,让我们来把它发布到munki服务器上,首先把它复制到munki服务器的pkgs目录里面,其实在pkgs目录里面,为了管理方便,管理员完全可以建立多层子目录,来形成一种目录式的分层结构。比如右图所示。 然后我们来把每个安装包的安装信息发布到pkgsinfo里面,只要使用makepkgsinfo命令,就可以轻松得到,当然有时你可能需要手动编辑一个pkgsinfo信息,以符合你的特殊要求。 注意,一旦我们决定使用子目录来分层管理各个安装包,并相应地生成了他们的pkgsinfo信息,请不要随便移动安装包的目录,否则,你需要重新生成各个安装包的pkgsinfo信息。 之后,让我们来把这些信息,组合到munki目录里面,只要使用makecatalog命令,就可以完成这个任务。 自此,登录造册的过程已经完毕。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-19_57158f4f15e7f.gif) ### 分组测试 这一步本来不是munki所要求的,只不过对于一个严谨的系统管理员来说,在正式发布之前,不仅要在制作安装包的时候考虑周全,同样地,一定要在发布之前,做好实际工作环境的测试工作,不仅是测试安装包的工作,同样是测试登陆造册的过程是否完全符合当初的需求。 ### 最终发布 完成测试,我们把安装包最终放置在manifest里面,这样它就成为了客户端可以使用安装的了。 这个过程只是需要编辑manifest目录里面的相应的文件,把各个软件名按照需求,比如是安装还是卸载,添加到指定的位置。 ### 部署 ### munki软件: 在早期的munki软件中,它的所有部分都是包含在一个单一的安装包中的,这个不利于我们管理员的最终发布,一方面需要做一些postflight的工作,另外,可能需要对不同的发布版本,对postflight进行必要的维护。 现在,munki软件是按照功能分开的,然后统一到一个包mpkg中,这样我们可以根据需要挑选不同的安装包。 目前它包括4个部分:core,admin,app和launchd。其中只有launchd部分需要客户端重新启动来完成安装步骤。 对于服务器部分,我们始终不需要安装任何munki软件。 对于客户端,我们需要安装core,app和launchd三个部分。 对于管理员电脑,我们需要安装core和admin,对于app,你可能需要。 ### 客户端 对于客户端,我们不仅要安装默认的munki包,还需要做客户定制。目前来说,定制包括下面的几个方面: 确定客户端所属的manifest。 确定安装的日程,也就是编辑各个launchd文件,他们存放在目录/Library/LaunchAgents/和/Library/LaunchDeamons/里面。 生成ManagedInstalls.plist文件,它存放在/Library/Preferences/目录里面。其中主要需要定义的是: 定义munki服务器的地址,需要把比如SoftwareRepoURL定义为http://your.business.name/update;把AppleSoftwareUpdatesOnly定义为False.InstallAppleSoftwareUpdates定义为False等等。 ### 服务器 确定服务器的位置和可用性,这需要根据你的内部的需要,比如你需要它被出差在外的人员访问吗?如果是,那么可能需要这个http向Internet公开,否则,就要担负VPN的开支。 这种更新是否很频繁,需要很多的系统资源?你可能需要多个munki服务器,一个负责承载pkgs,另外的承担pkgsinfo,manefest和catalog的服务。 安全性是否很重要?如果是,你可能需要开启和设置https服务,或者是简单的http认证服务等。 ### 负载的考虑 服务器的负载平衡等可能是你,把munki的每个功能分布到不同的服务器,是munki内部支持的一个简单方式,其它的硬件软件负载平衡,要根据你的网络情况和需要而定。 同样的,网络负载也是一个重要的考虑因素。曾经有一个技术员,把所有的客户端设置成,在一个特定时间访问某一个特定的服务器,而且这个功能是集成在基本系统镜像文件中的,这样造成该部门一到该时间,网络就会奇慢, 还好得益于Unix的核心,它可以被轻易的禁止。 munki提供了内置的随机延时功能,也就是,它访问munki服务器的时间一到,它会随机的延时一段时间后,再启动访问操作,这样可以比较有效的分散网络操作。不过,这也和具体的更新文件大小相关,比如一个4GB的更新包的下载可能需要10分钟,在此期间其他的访问会减慢这个更新的下载进程,如此的积累,定会影响网络其它业务的进行。 ### 客户的更新 munki软件本身是发展很快的,所以,在客户端也需要对munki本身进行升级。升级的考虑和安装的考虑是相同的,不过是可以通过munki的机制本省进行升级的。 ### 客户化 ### 定制的考虑: ### 定制自动检查日程 ### 定制客户的货单属性 ### 客户操作的培训 ### 苹果升级安装 ### 一个简单示例 这里我们演示一个实际的简单例子。我们在两台Mac机器上实现,其中一台打开http服务作为服务器,同时它也是一个受管的munki客户端,可以访问自己系统的http服务下载安装更新。另外一台机器是管理电脑。你也可以配置一台Windows或者Linux及其作为munki服务器。 ### 准备工作: 首先下载最新的munki软件包,到[官方网站下载](http://code.google.com/p/munki/downloads/list). 在管理机上,比如admin1,安装munki软件。你可以根据上面部署一节的内容挑选相应的部分安装。 ### 服务器 #### 服务器配置 在服务器电脑的共享偏好中,打开web sharing。 测试是否成功,可以在任何一台机器上,在Safari上输入该服务器的地址,比如: http://* s456.mydomain.com/repo,*如果可以正确显示,配置就成功了。 在Finder窗口中,转换到/Library/WebServer/Documents目录,创建一个子目录repo,在它里面建立另外4个目录,pkgs,pkgsinfo,catalog,和manifest。 确定repo及其所有的子目录和文件的属性,你和管理员组都有read & write权限,而其他人至少都有read权限。 上面的步骤集成在一个命令行为: *ROOT_DOCU="/Library/WebServer/Documents"* *mkdir -p $ROOT_DOCU/repo/pkgs* *mkdir -p $ROOT_DOCU/repo/pkgsinfo* *mkdir -p $ROOT_DOCU/repo/catalogs* *mkdir -p $ROOT_DOCU/repo/manifests* *mkdir -p $ROOT_DOCU/repo/Configurations* *chmod –R 774 $ROOT_DOCU/repo* 我们为了维护方便,同时打开文件共享服务,并共享/Library/WebServer/Documents/repo/目录,共享名repo。这样我们可以方便的在管理机上进行远程管理munki的服务器配置。 把下面的内容复制到一个文本编辑器中,比如textedit.app,然后保存位production的**文本文件****,**注意不是rtf格式的文件,要是纯文本文件。 *<?xml version="1.0"encoding="UTF-8"?>* *<!DOCTYPE plist PUBLIC "-//AppleComputer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">* *<plist version="1.0">* *<dict>* *       <key>catalogs</key>* *        <array>* *               <string>testing</string>* *        </array>* *       <key>managed_installs</key>* *        <array>* *               <string>Firefox</string>* *               <string>**ServerAdministrationSoftware</string>* *        </array>* *</dict>* *</plist>*** 如果你熟悉plist文件,那么可以看出,这个就是一个标准的文本格式的plist文件,你当然可以用Property List Editor编辑。 #### 软件下载和打包 现在让我们下载两个软件,一个是FireFox一个是ServerAdminTools,它们分别是两种安装形式,FireFox是直接的拖拽到Applications目录,一种是flat的pkg格式。对于这两个包,我们不用重新打包就可以使用。 在管理机上,确定服务器电脑的DNS名称是正确的,比如它是s456.mydomain.com。这个信息很重要,以后要用。 把共享的文件夹映射到管理机上: *mount afp://s456.mydomain.com/repo* 这样我们就可以通过访问/Volumes/repo访问服务器上的repo了。 然后把它们复制到/Volumes/repo/pkgs/目录中。 #### 管理工具使用([PkginfoFiles](http://code.google.com/p/munki/wiki/PkginfoFiles)) 在管理机上,执行下面命令来生成pkgsinfo文件: */usr/local/munki/makepkginfo/Volumes/repo/pkgs/firefox5.dmg > /Volumes/repo/pkgsinfo/firefox5.pkginfo* */usr/local/munki/makepkginfo /Volumes/repo/pkgs/ServerAdministrationSoftware.pkg> /Volumes/repo/pkgsinfo/ ServerAdministrationSoftware.pkginfo* 如果没有错误,继续执行下面命令: */usr/local/munki/makecatalog /Volumes/repo/* ### 客户端配置 #### 软件安装 安装munki软件在客户端上,也就是s456机器上。需要重新启动。 #### 配置 执行下面的命令来进行基本的配置: *defaults write /Library/Preferences/ManagedInstallsClientIdentifier –string “testing”* *defaults write /Library/Preferences/ManagedInstallsSoftwareRepoURL –string “http:// s456.mydomain.com/repo”* *defaults write /Library/Preferences/ManagedInstallsAppleSoftwareUpdatesOnly –bool false* *defaults write /Library/Preferences/ManagedInstallsInstallAppleSoftwareUpdates –bool false* ### 测试 如果你希望等待,那么可以等待客户机自动检查更新,自动下载,自动安装。不过为了测试我们来手动安装。 在客户机上的/Applications/Utilities目录中,安装了一个ManagedSoftware Update.app程序,它是一个类似苹果Software Update程序的软件,可供客户手动安装受管软件的安装。 执行它,如果配置正确,那么你可以看见FireFox和**ServerAdministrationSoftware两个软件在列表中,只要是按照提示安装就可以了。 完成了! ### 颗粒化管理 ### 基本意图 ### 如何实现 ### 安全 **目前来****说****,****它可以提供了基本的安全保****护****,****比如使用****http简单认证****,****或者是****https认证****,****** ******** ### 真实示例简述 ### 今后发展 **集成更多功能****:****审计****功能****** **支持更多的****设备****:****iPhone, iPod touch, iPad,****其它****设备****,****Andorid****等****.****** **支持更多的系****统****:****Windows, Linux****等******
';

Mac OS X:AFP和SMB共享配置详细配置

最后更新于:2022-04-01 10:56:33

在Mac OS X的System Preferences里面对文件共享的配置,可能不够灵活,或者说有时不够明显,比如,无法从GUI中明确分辨,哪个共享时可以通过AFP的,哪个是SMB的,哪个是两者都可以。那么通过下面的方法就可以具体了解某一个共享名的具体配置情况。比如共享名是DS,执行命令行: dscl . -read /SharePoints/DS 得到下面的信息,说明它通过AFP和SMB共享,共享名称都是DS,路径是/Users/Shared/DS等等信息。 dsAttrTypeNative:afp_guestaccess: 1 dsAttrTypeNative:afp_name: DS dsAttrTypeNative:afp_shared: 1 dsAttrTypeNative:directory_path: /Users/Shared/DS dsAttrTypeNative:ftp_name: DS dsAttrTypeNative:sharepoint_group_id: 6394A3E4-2542-4CEF-949F-FE35909DB095 dsAttrTypeNative:smb_createmask: 644 dsAttrTypeNative:smb_directorymask: 755 dsAttrTypeNative:smb_guestaccess: 1 dsAttrTypeNative:smb_name: DS dsAttrTypeNative:smb_shared: 1 AppleMetaNodeLocation: /Local/Default RecordName: DS RecordType: dsRecTypeStandard:SharePoints   当然可以修改其中的内容以达到自己的要求,比如改变SMB共享名称: dscl . -change /SharePoints/DS smb_name DS SMB_DS   以上内容都是关于Mac OS X工作端平台的,不是服务器版本,在Server上面的GUI配置要灵活很多。 在10.6系统上通过测试,在10.5上应该工作,但是没有测试。 2011-05-28
';

Mac OS X的Spotlight综述

最后更新于:2022-04-01 10:56:31

# Mac OS X的Spotlight综述 ### 关于Spotlight的简述     Spotlight是苹果OS X系统里的亮点之一,它的快速查找,是Windows等其它系统所难望其项背的。特具有如下特点: -     它很快,相当快而且聪明。 -     它存在好多地方,Finder,System menu, Open和Save对话框, Mail等等。 -     它会自动为安装的磁盘建立/更新索引,除了网络和DVD磁盘等. -     它不仅搜索普通文件,还有联系人,email,iTunes里的音乐,iPhoto里的照片,日历中的事件,系统文件等等。 -     它不会做的:隐藏文件(.hidden),不可见文件(invisible),在隐藏或者不可见文件夹里的文件等。 -     除了对所有用户目录建立索引,还对/Applications,/Library/PreerencePanes /System/Library/PreerencePanes启作用 -     在Finder里面,Command+F来打开一个所有窗口 -     可以对各种文件的多种属性进行搜索,比如File lable,甚至是System Files等等。 -     相关的系统进程: mds, mdimport, mdworker. -     即便是安全模式,它也是可以使用的。 -     它支持插件,适合的插件用来搜索特定的数据库里的项目。 -     随着文件的增多,它占用更多的磁盘空间,不过用户觉察不到。 -     其它的选择,Find Any File, EasyFind, Find File等等 ### 基本使用: - Spotlight: 在系统菜单栏中,也就是屏幕的右上角的放大镜按钮,点击它,或者使用快捷键(Command+Sapce),在下拉的Spotlight蓝色搜索栏中输入要查找的特征,它就会在下方列出相关的项目。我常用的是,输入一个程序的名字,比如是计算器,我只输入Cal,计算器就会称谓第一个备选者,我按Enter回车,就可以启动计算器程序了。 - Finder中: 还可以在Finder窗口中的工具栏的最右边,也是搜索栏,输入查找特征,系统也会随时列出相关的项目。搜索时,文件列表区域的顶端,会出现一个Search的表头,可以方便切换搜索的范围-当前电脑还是启动磁盘,和查找根据-是查找内容相关还是单单文件名相关。和Spotlight不同的是,你可以进行高级查找,也就是添加/使用各种的搜索条件。只要点击Search条的最有边的“+”小按钮,下方又出现一条,这里你可以添加一个一个的条件,最左边是条件的类型,最常用的是文件类型,修改时间,创建时间,上次打开时间,后面就是具体条件,随时输入,下方列表随时更新,非常方便。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-19_57158f4eed7a2.gif) - Save/Open 还有在你保存/打开文件的时候,也可以使用上面Finder的搜索方法。具体操作和上边类似。 - 改变搜索结果顺序: 进入System Preerences的Spotlight,拖动每一项就可以改变顺序,去除选择的话,这一类的结果就不会出现在搜索结果中。 ### 基本的排错:     在一般的情况下,它工作得相当得文件,但是在升级安装或者是被自己多次修改过的系统中,会出现Spotlight不工作的问题。解决问题可以遵循下面的步骤来尝试,尝试每一步之后,都需要等待一段时间,可能时数秒,也可能是一两分钟不等,过长的时间等待一般不需要。     1: 重新启动电脑         这个总是第一个想到的     2: 删除com.apple.spotlight.plist文件         这个文件在挡墙用户个人文件家的~/Library/Preferences文件夹中     3: 进入在System Preferences中的Spotligh的Privacy中,把系统磁盘添加到列表中,等候几秒中,然后再从中删除。一般的情况到此为止,都可以解决了。     4: 杀掉SystemUIServer进程         进入在Utilities文件夹中的Activity Monitor中,找到并选择"SystemUIServer",点"Quit Process"。等一会儿,系统菜单条会重新出现。     5: 命令行         sudo find / -iname '.Spotlight-V100' -type d -maxdepth 3 -print0 | xargs -0 -t -n1 sudo rm -rf         sudo mdutil -E /     6: 再有就是详细阅读后面的解读,自己尝试各个方式。 ### 停止它建立索引:         虽然它很好用也有很多人喜欢它,你依然可能出于某种想法希望停止它,无论是临时的还是永久的。比如有的嫌它太占用资源,导致系统速度下降;有的说它崩溃,还不如没有。还有一种情况,可能你真的希望临时禁止它,或者禁止部分;还有的时候Spotlight可能产生安全隐患,一个不希望被其它用户搜索的,却可以被搜索,虽然可能不能存取,但是也是不安全(多数情况可能是使用习惯不好造成的)。总之,我们希望用户自己控制它的打开,部分打开,或者完全禁止。 ### 命令行: 1. hostconfig 如果你运行的是Mac OS X 10.5雪豹以前的系统,那么有一种方法可以禁止它。就是编辑/etc/hostconfig里面,修改SPOTLIGHT=-No-. 重新打开也简单,改成默认的-YES-,重新启动系统之后就可以。不过这个方法需要你有管理员权限。 1. 使用GUI 在System Preferences里的Spotlight,在Privacy标签中,把本机的硬盘符,拖到列表中,系统提示就确认,之后,Spotlight就不管用了。 ***版权信息**: 本着开放交流的原则欢迎转载,除非明确声明"谢绝转载"等字样. **所有文章/图片/代码(除转载和翻译),版权均属文章作者**. 转载请遵守下面规则:  1)保持文章的完整性; 2)不得以盈利为目的; 3)完整标注文章作者[Tony Liu@[中国在线教育](http://blog.csdn.net/afatgoat)]和文章中标注的所有版权信息。 其它事宜,如:需要商业用途或以盈利为目的的、或者部分转载的等等,请与本作者联系: TonyLiu2CA@yahoo.com* 如果禁止了当前的系统硬盘,Spotlight和Finder中都无法使用搜索功能了,在搜索栏中无法输入。 当然可以禁止查找特定的目录,同样的方法,拖动到列表里就好。一旦一个目录或者磁盘被拖放在里边,Spolight会立刻停止对他建立索引,而且也无法再从Finder找到里面的文件,虽然已经储存的索引还依然存在于系统中。 一旦一个目录被添加到Privacy里面,在搜索里面就不会出现在搜索结果中。 在以前的系统里可能会出现问题,比如Spotlight正在建立索引的时候,它可能产生一个mds-crash-state的文件,这样即使你把它从Privacy里面去除,依然无法对他重新建立索引。解决的办法是,或者卸载这个磁盘后再安装上,或者重新启动系统,或者删除这个文件(.Spotlight-V100目录中),或者运行重新索引命令: sudo mdutil -E /path_to_volume 要想打开,就把它从列表中删除,删除后,Spotlight会自动更新,这个速度根据你的系统和文件多少等,可能会持续数分钟,或者更长。 1. sudo mdutil -i off /path_to_volume 这个命令可以应用于一个磁盘(分区),不能应用于一个目录。而这个被禁止的磁盘不会出现在Spotlight的Privacy列表里面。 如果是sudo mdutil -i off / 也就是对整个启动磁盘禁止索引,运行这个命令的结果:系统不会启动mds来对磁盘进行后台索引,但是在Finder中依然可以使用Find功能,只不过这个功能就如同Windows里面的普通搜索类似了,速度慢,因为没有了可以使用的数据索引,和命令行下的Find命令类似,只不过它不查找程序或者各种包里面的内容。比较上面在GUI下的Pravicy的禁止,里面有些差异。这个功能有的时候可能还是用得到的,比如你不希望系统随时建立索引,但是同时还要保留在Finder里面查找文件的功能。 ### 其它方式:      使用第三方软件,比如Onyx/QuickSilver等 ### 命令行和GUI的关系:     在Mac OS X 10.6以前的版本,命令行和System Preferences里的Spotlight是不太兼容的两个部分。不过这种情况已经得到改善     比如,在Spotlight里面把一个目录添加到Privacy里面了,命令行依然可以运行 -i off或者-i on,但是在雪豹中,已经是不行了,当你使用-i on的时候,它会提示 Indexing and searching disabled.     在比如,当你把一个目录添加到Privacy里面后,以前的版本可能不会立刻删除索引数据,而现在的版本会立刻删除。     前面也说了,在命令行禁止索引,在GUI中依然可以搜索文件。 ### 其它命令     sudo mdutil -E /     重新建立系统磁盘的索引。如果在GUI中Pravicy里面被禁止了,那么这条命令不起作用。     sudo launchctl unload /System/Library/LaunchDaemons/com.apple.metadata.mds.plist     停止mds服务。下次系统重新启动后,mds服务会重新启动。     sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.plist     停止mds服务。下次系统重新启动后,mds服务都不会重新启动。     sudo launchctl load /System/Library/LaunchDaemons/com.apple.metadata.mds.plist     停止之后,如果需要立刻启动mds服务,运行这个命令。   ### Under the Hood:     下面的内容千万比出于好奇尝试,只有在你真正了解下面所说的内容之后再使用,否则后果自负。     Spotlight的索引建立在,各个磁盘的目录下面的.Spotlight隐藏目录中。     在系统偏好的Spotlight的Privacy中的列表内容,存放在叫做Exclusions.plist的文件中。     而搜索结果的顺序选项,则在当前用户的的个人文件夹中的com.apple.spotlight.plist文件中定义。     对于希望不使用GUI方式操作Privacy的用户,就需要使用命令行了,下面就是一个例子。 # Start defaults delete /.Spotlight-V100/Exclusions defaults write /.Spotlight-V100/Exclusions  Exclusions -array launchctl unload /System/Library/LaunchDaemons/com.apple.metadata.mds.plist launchctl load /System/Library/LaunchDaemons/com.apple.metadata.mds.plist # End     还有一个彻底的方式: # Start     sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.plist     mkdir /System/Library/LaunchAgnets.backup     sudo mv /System/Library/LaunchAgnets/com.apple.metadata_mdwrite /System/Library/LaunchAgnets     cd /System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Support/     tar -cvf mdworkstuff.tar ./ #(saves all md* to a tarball in case you ever want it back)     then :     rm mdworker     rm mdworker32     rm mds     rm mdwrite # End     Tony Liu in Calgary 2011, 03, 03 -18 Windchill -35
';

Mac OS X: airport命令的参数

最后更新于:2022-04-01 10:56:29

Usage: airport <interface> <verb> <options>     <interface>     If an interface is not specified, airport will use the first AirPort interface on the system.     <verb is one of the following:     prefs    If specified with no key value pairs, displays a subset of AirPort preferences for         the specified interface.         Preferences may be configured using key=value syntax. Keys and possible values are specified below.         Boolean settings may be configured using 'YES' and 'NO'.         DisconnectOnLogout (Boolean)         JoinMode (String)             Automatic             Preferred             Ranked             Recent             Strongest         JoinModeFallback (String)             Prompt             JoinOpen             KeepLooking             DoNothing         RememberRecentNetworks (Boolean)         RequireAdmin (Boolean)         RequireAdminIBSS (Boolean)         RequireAdminNetworkChange (Boolean)         RequireAdminPowerToggle (Boolean)         WoWEnabled (Boolean)     logger    Monitor the driver's logging facility.     sniff    If a channel number is specified, airportd will attempt to configure the interface         to use that channel before it begins sniffing 802.11 frames. Captures files are saved to /tmp.         Requires super user privileges.     debug    Enable debug logging. A debug log setting may be enabled by prefixing it with a '+', and disabled         by prefixing it with a '-'.         AirPort Userland Debug Flags             DriverDiscovery             DriverEvent             Info             SystemConfiguration             UserEvent             PreferredNetworks             AutoJoin             IPC             Scan             802.1x             Assoc             Keychain             RSNAuth             WoW             AllUserland - Enable/Disable all userland debug flags         AirPort Driver Common Flags             DriverInfo             DriverError             DriverWPA             DriverScan             AllDriver - Enable/Disable all driver debug flags         AirPort Driver Vendor Flags             VendorAssoc             VendorConnection             AllVendor - Enable/Disable all vendor debug flags         AirPort Global Flags             LogFile - Save all AirPort logs to /var/log/airport.log <options> is one of the following:     No options currently defined. Examples: Configuring preferences (requires admin privileges)     sudo airport en1 prefs JoinMode=Preferred RememberRecentNetworks=NO RequireAdmin=YES Sniffing on channel 1:     airport en1 sniff 1 LEGACY COMMANDS: Supported arguments:  -c[<arg>] --channel=[<arg>]    Set arbitrary channel on the card  -z        --disassociate       Disassociate from any network  -I        --getinfo            Print current wireless status, e.g. signal info, BSSID, port type etc.  -s[<arg>] --scan=[<arg>]       Perform a wireless broadcast scan.                    Will perform a directed scan if the optional <arg> is provided  -x        --xml                Print info as XML  -P        --psk                Create PSK from specified pass phrase and SSID.                    The following additional arguments must be specified with this command:                                   --password=<arg>  Specify a WPA password                                   --ssid=<arg>      Specify SSID when creating a PSK  -h        --help               Show this help   Example: sudo /System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport en1 prefs RequireAdminPowerToggle=No
';

Mac: 网络用户遇到Adobe Reader 9.x/10.x异常退出的解决

最后更新于:2022-04-01 10:56:27

# **Mac: 网络用户遇到Adobe Reader 9.x/10.x异常退出的解决** ### 异常退出表现: 一个用户目录存放在AFP网络服务器上的网络用户登陆后,初次运行Adobe Reader 9.x/10.x时,Reader正常询问用户接收授权证书,以及是否使用Reader来打开所有的PDF文件等问题后,Reader菜单和程序图标在Dock上停留短暂时间后会突然退出,并显示下图的运行错误提示:   ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-19_57158f4eab170.gif) 在以后的运行中,同样是发生异常退出,用户根本无法使用Adobe Reader。 而本地用户以及移动用户(用户目录存放在本地磁盘),却没有这个问题。在最初的测试中发现,这个问题似乎和客户端和服务器端系统本身的版本无关,只同网络用户和Adobe Reader软件本身有关。 ### 错误跟踪:   跟踪系统的logs的结果是: ------------------------------------------------------------------------------------------------------------------------ 2/10/11 1:31:53 PM    Dock[10487]    SQLite failure in directoryCreated for <ECDirectory: 0x10183fd60> {path=/Network/Servers/s374rls2.com/UserData/374-123/Documents/} lineNum=759 err=5 (database is locked) 2/10/11 1:32:08 PM    [0x0-0xe90e9].com.adobe.Reader[10567] terminate called after throwing an instance of 'SQLiteUtils::SQLiteException' 2/10/11 1:32:10 PM    com.apple.launchd.peruser.2045665344[8759] ([0x0-0xe90e9].com.adobe.Reader[10567]) Job appears to have crashed: Abort trap 2/10/11 1:32:10 PM    ReportCrash[10578]    Saved crash report for AdobeReader[10567] version 9.3.0 (9.3.0) to /Network/Servers/s374rls2.com/UserData/374-123/Library/Logs/DiagnosticReports/AdobeReader_2011-02-10-133210_w374-764.crash ------------------------------------------------------------------------------------------------------------------------ 再来看看错误报告的前面部分的内容: ------------------------------------------------------------------------------------------------------------------------ Process:         AdobeReader [9435] Path:            /Applications/Adobe Reader 9/Adobe Reader.app/Contents/MacOS/AdobeReader Identifier:      com.adobe.Reader Version:         9.3.0 (9.3.0) Code Type:       X86 (Native) Parent Process:  launchd [8759] Date/Time:       2011-02-10 13:23:17.423 -0700 OS Version:      Mac OS X 10.6.3 (10D2063a) Report Version:  6 Interval Since Last Report:          5812 sec Crashes Since Last Report:           2 Per-App Interval Since Last Report:  27 sec Per-App Crashes Since Last Report:   2 Anonymous UUID:                      AA88CA84-2CD6-42AF-A4ED-D41DD8569C16 Exception Type:  EXC_CRASH (SIGABRT) Exception Codes: 0x0000000000000000, 0x0000000000000000 Crashed Thread:  0  Dispatch queue: com.apple.main-thread Application Specific Information: abort() called Thread 0 Crashed:  Dispatch queue: com.apple.main-thread 0   libSystem.B.dylib                 0x98449132 __kill + 10 1   libSystem.B.dylib                 0x98449124 kill$UNIX2003 + 32 2   libSystem.B.dylib                 0x984db8e5 raise + 26 3   libSystem.B.dylib                 0x984f199c abort + 93 4   libstdc++.6.dylib                 0x9967bfda __gnu_cxx::__verbose_terminate_handler() + 433 5   libstdc++.6.dylib                 0x9967a17a __cxxabiv1::__terminate(void (*)()) + 10 6   libstdc++.6.dylib                 0x9967a1ba __cxxabiv1::__unexpected(void (*)()) + 0 7   libstdc++.6.dylib                 0x9967a2b8 __gxx_exception_cleanup(_Unwind_Reason_Code, _Unwind_Exception*) + 0 8   com.adobe.Acrobat.framework       0x8064ecc7 AcroSecurityBailOutImpl + 6611123 9   com.adobe.Acrobat.framework       0x8061fc76 AcroSecurityBailOutImpl + 6418530 10  com.adobe.Acrobat.framework       0x8061eed5 AcroSecurityBailOutImpl + 6415041 11  com.adobe.Acrobat.framework       0x806204c0 AcroSecurityBailOutImpl + 6420652 12  com.adobe.Acrobat.framework       0x809599f3 0x7fe27000 + 11741683 13  com.adobe.Acrobat.framework       0x80959b9e 0x7fe27000 + 11742110 14  com.adobe.Acrobat.framework       0x805be074 AcroSecurityBailOutImpl + 6018144 15  com.adobe.Acrobat.framework       0x80443bc6 AcroSecurityBailOutImpl + 4468658 16  com.adobe.Acrobat.framework       0x80443db1 AcroSecurityBailOutImpl + 4469149 17  com.adobe.Acrobat.framework       0x7ff69443 RunAcrobat + 1311411 18  com.adobe.Acrobat.framework       0x7ff6917a RunAcrobat + 1310698 19  com.apple.CoreFoundation          0x96c8976b __CFRunLoopRun + 8059 20  com.apple.CoreFoundation          0x96c870f4 CFRunLoopRunSpecific + 452 21  com.apple.CoreFoundation          0x96c86f21 CFRunLoopRunInMode + 97 22  com.apple.HIToolbox               0x9133b15c RunCurrentEventLoopInMode + 392 23  com.apple.HIToolbox               0x9133af11 ReceiveNextEventCommon + 354 24  com.apple.HIToolbox               0x9133ad96 BlockUntilNextEventMatchingListInMode + 81 25  com.apple.AppKit                  0x94a7c0fd _DPSNextEvent + 847 26  com.apple.AppKit                  0x94a7b93e -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 156 27  com.apple.AppKit                  0x94a3dbc7 -[NSApplication run] + 821 28  com.adobe.Acrobat.framework       0x7fe29b8d RunAcrobat + 2557 29  com.adobe.Acrobat.framework       0x7fe292ce RunAcrobat + 318 30  com.adobe.Reader                  0x00002e8b start + 2371 31  com.adobe.Reader                  0x0000264a start + 258 32  com.adobe.Reader                  0x00002571 start + 41 ... ... ------------------------------------------------------------------------------------------------------------------------ ### 分析和测试: 从logs中的记录看,是Adobe Reader内置的SQLiteUtils在访问它的数据库的之后,无法锁定,从而简单地抛出一个致命错误并退出,致使后面的程序无法继续运行。而网络用户相关的文件访问,是通过AFP网络协议来实现的,所以很可能是因为它不支持AFP网络协议造成的。 其实,在旧旧版本中旧有过类似的问题,只不过在Adobe Reader 8.1.3中已经解决了这个问题,可是在新版本中9.x和10.x中这个类似的问题又出现了,而且至今不再解决这个问题。   查看Adobe的preference文件,没有发现问题,而它产生的一些字体缓存文件,却出现了问题。比如~/Library/Application Support/Adobe/Acrobat/9.0_x86目录中的,AdobeCMapFnt09.lst和AdobeComFnt09.lst的文件大小是0KB, 而正常的应该是4KB,这说明至少在生成这两个文件时产生了错误。   ***版权信息**: 本着开放交流的原则欢迎转载,除非明确声明"谢绝转载"等字样. **所有文章/图片/代码(除转载和翻译),版权均属文章作者**. 转载请遵守下面规则:  1)保持文章的完整性; 2)不得以盈利为目的; 3)完整标注文章作者[Tony Liu@[中国在线教育](http://blog.csdn.net/afatgoat)]和文章中标注的所有版权信息。 其它事宜,如:需要商业用途或以盈利为目的的、或者部分转载的等等,请与本作者联系: TonyLiu2CA@yahoo.com* * * 把其它本地用户中的9.0_x86目录中的所有文件复制过来,是第一个想到的方法,可以问题依旧。所以,SQLiteUtils不仅仅是在生成这些文件的时候有错误,就连读取都不行,那么就只好把SQLiteUtils需要存储的文件重新定向到本地硬盘。经过测试,这个方法的确奏效,不过也走了一点弯路,比如不能把Acrobat目录连接到本地,虽然9.0_x86是其中的一个子目录,而只能把9.0_x86目录设置成软连接。 ### 问题解决: 问题找到了,经过测试也是可以解决问题的,不过对于网络用户可以通过两个方式来最终解决这个问题。 ### 1. 登录脚本钩子: 第一个方法是使用登录脚本钩子的方式,如果你单位的系统部署的时候,系统映像里面已经包含了登录脚本钩子的实现,那么就可以使用这个方法。这个方法需要把脚本部署在每个客户端机器上,所以需要一些努力才能确认部署完成,特别是大型环境和移动系统较多的情形。而且这个方法,适合于针对只有Adobe安装的机器,而不是针对用户,这样,只有安装了Adobe的机器才需要   具体方法是江下面的语句加入到你的登录脚本中。 # Create new 'Caches' folder on the local hard drive `mkdir -p -m 777 "/private/tmp/$userLoggedIn/9.0_x86"`; `mkdir -p "$userHomeDir/Library/Application Support/Adobe/Acrobat"`; # Create symbolic link to point user's 'Caches' folder to local directory `ln -s -f -h "/private/tmp/$userLoggedIn/9.0_x86" "$userHomeDir/Library/Application Support/Adobe/Acrobat/9.0_x86"`; ### 2. 工作组管理器:   而使用Workgroup Manager设置,对用户/用户组/机器/机器组,进行组合控制,更加灵活。 选择所要设置的目标,选择Preferences->Details, 选择文件夹重定向,并编辑它,添加如图的各个键值。   ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-19_57158f4ec47dd.gif)   结束语: 至此,该问题解决,对于10.x版本的只要稍作修改,同样可以轻松解决。 其实,Adobe Acrobat等其它软件,也有这个运行错误,而这个思路同样适用于它们。       Tony Liu, 2011-02-13 于Calgary
';

Mac OS X 10.6.6更新之后NTFS只读的解决

最后更新于:2022-04-01 10:56:24

如果你按照<[**Mac OS X:雪豹内置支持读写NTFS卷**](http://blog.csdn.net/afatgoat/archive/2009/09/22/4579112.aspx)>一文中的Update下面的方法变更了NTFS读写功能,在你安装了Mac OS X 10.6.6更新包之后,你可能无法再次无法写NTFS卷,这是因为它被更新包"修复"了。需要再次按照该方法重新变更一次。  
';

Mac OS X: 文件图标制作和变更(Resource Fork)

最后更新于:2022-04-01 10:56:22

### Mac OS X: 文件图标变更(Resource Fork)         在Mac系统里面,文件的一些属性是存储在Resource Fork里面的,这个在其它的系统里面基本上是没有的,是Mac系统的特点。 Resource Fork是存储文件结构化数据的存储方式,是和Data Fork相对比而言的, Data Fork就是我们最普通的一个文件的内容的存储方式了。         那么Resource Fork里面到底存储什么呢?其实,如果你开发程序,基本上说,可以存储任何东西,但是造成的问题是,在当今的互联环境里不实用。         而在Mac系统里面,它主要是保存,文件在GUI环境里面显示图标时的图标,窗口形状,程序码等等           这里只说图标-icon. 在GUI环境里面,图标的设定比较容易,比如复制一个图形然后在一个文件的信息窗中粘贴图标旧恶可以了。           下面的方法,也有使用GUI程序的部分,也有使用命令行的部分,命令行适合于管理员的管理和自动化。   # ----------------------------- # For files # 1. Create a resource fork file (tempfork) #     . From another file using derez command #     . or use icongrapher to save as resource file # 2. update file resource fold with the tempfork file #     . using rez command #     . or use icongrapher to save into a file # 3. "setfile -a C" command # ----------------------------- derez -only icns sourcefile > tempicns.rsrc rez -a tempicns.rsrc -o recipienfile setfile -a C recipienfile # ----------------------------- # For Folders # # 1. (same as the 1. step in For Files) # 2. copy the tempfork file in the folder #     cp tempfork /folder/Icom^M # 3. "setfile -a C" command # ----------------------------- derez -only icns sourcefile > tempicns.rsrc #cp tempfork TheFolder/Icon^M setfile -a C TheFolder # ----------------------------- # For Volumes # create a .VolumeIcon.icns file in the root of the Volume # This .icns file is actually a icon file which is save in # Icon Composer or Preview. # 3. "setfile -a C" command # ----------------------------- CandyBar can be used for saving other format pictures to Mac icns Ref: http://www.macgeekery.com/gspot/2006-09/copying_a_folders_icon_with_terminal_commands
';