XCoderLiu's Blog

An iOS developer @ Tencent

吾生也有涯,而知也无涯!


我的 Github

Shell 编程实践

子文件夹

subFolders=`find $parentFolder -type d -maxdepth 1 -mindepth 1`

进度条

function ProgressBar {
# Process data
let _progress=(${1}*100/${2}*100)/100
let _done=(${_progress}*4)/10
let _left=40-$_done
# Build progressbar string lengths
_fill=$(printf "%${_done}s")
_empty=$(printf "%${_left}s")

printf "\rProgress : [${_fill// /#}${_empty// /-}] ${_progress}%%"

}

shell 实战脚本打包

projectPath=/Users/liuzhimin/Dropbox/Personal?Code/Project
thearchviePath=/Users/liuzhimin/Desktop
ipaPath=/Users/liuzhimin/Desktop
projectname=PackageProject
resourcefolder=res_dev
version=$1

cd $projectPath

######copy Dev file######
echo "😀  😀  😀  i will start for development package!"
echo "***************** copy Dev public file start *****************"

cp -rf $projectPath/$resourcefolder/AppIcon.appiconset $projectPath/ProjectClient/Images.xcassets

cp -rf $projectPath/$resourcefolder/InfoPlist.strings/*.lproj $projectPath/ProjectClient/

cp -rf $projectPath/$resourcefolder/Localizable.strings/*.lproj $projectPath/Resources/

cp -rf $projectPath/$resourcefolder/Multiversion  $projectPath/ProjectClient/Images.xcassets

cp -rf $projectPath/$resourcefolder/ProjectClient-InfoDev.plist  $projectPath/ProjectClient/ProjectClient-Info.plist

cp -rf $projectPath/$resourcefolder/configDev.xml  $projectPath/ProjectClient/config.xml

cp -rf $projectPath/$resourcefolder/ClientMgrCfgDev.xml  $projectPath/ProjectClient/meetingMgrCfg.xml

echo "***************** copy Dev over *****************"


######start Dev bulild######
echo "***************** start clean Dev workspace *****************"

xcodebuild clean

rm -rf $thearchviePath/ProjectApp.xcarchive

rm -rf $thearchviePath/ProjectDev.xcarchive

rm -rf $thearchviePath/ProjectIntranet.xcarchive

rm -rf $ipaPath/Project_for_iOS_${version}_test.ipa

rm -rf $ipaPath/Project_for_iOS_${version}_appstore.ipa

rm -rf $ipaPath/Project_for_iOS_${version}_appstore_test.ipa

xcodebuild -project $projectname.xcodeproj -scheme $projectname -configuration Release clean

echo "***************** clean Dev workspace over *****************"

echo "***************** start build Dev workspace *****************"

xcodebuild -project $projectname.xcodeproj -scheme $projectname -configuration Release

echo "***************** build Dev workspace over *****************"

echo "***************** start export Dev archive *****************"

xcodebuild -project $projectname.xcodeproj -scheme $projectname archive -archivePath $thearchviePath/ProjectDev.xcarchive

echo "***************** export Dev archive over *****************"

echo "***************** start export Dev ipa app *****************"

xcodebuild -exportArchive -archivePath $thearchviePath/ProjectDev.xcarchive -exportPath $ipaPath -exportOptionsPlist projectDev.plist

mv $ipaPath/ProjectClient.ipa $ipaPath/Project_for_iOS_ ${version}_test.ipa

echo "***************** export Dev ipa over *****************"


###### Intranet test package ######
echo "😂  😂  😂  now Intranet test package!"
cp -rf $projectPath/$resourcefolder/configIntranet.xml  $projectPath/ProjectClient/config.xml

cp -rf $projectPath/$resourcefolder/meetingMgrCfgIntranet.xml  $projectPath/ProjectClient/meetingMgrCfg.xml

#xcodebuild -project $projectname.xcodeproj -scheme $projectname -configuration Release

xcodebuild -project $projectname.xcodeproj -scheme $projectname archive -archivePath $thearchviePath/ProjectIntranet.xcarchive

xcodebuild -exportArchive -archivePath $thearchviePath/ProjectDev.xcarchive -exportPath $ipaPath -exportOptionsPlist projectDev.plist

mv $ipaPath/ProjectClient.ipa $ipaPath/Project_for_iOS_${version}_Intranet_test.ipa

######copy App file######
echo "😂  😂  😂  then App & APP test package!"
echo "***************** copy App public file start *****************"

cp -rf $projectPath/$resourcefolder/configApp.xml  $projectPath/ProjectClient/config.xml

cp -rf $projectPath/$resourcefolder/meetingMgrCfgApp.xml  $projectPath/ProjectClient/meetingMgrCfg.xml

cp -rf $projectPath/$resourcefolder/ProjectClient-InfoApp.plist  $projectPath/ProjectClient/ProjectClient-Info.plist

echo "***************** copy App over *****************"

echo "***************** start build App workspace *****************"

#xcodebuild -project $projectname.xcodeproj -scheme $projectname -configuration Release

echo "***************** build App workspace over *****************"

echo "***************** start export App archive *****************"

xcodebuild -project $projectname.xcodeproj -scheme $projectname archive -archivePath $thearchviePath/ProjectApp.xcarchive

echo "***************** export App archive over *****************"

echo "***************** start export App ipa app *****************"

xcodebuild -exportArchive -archivePath $thearchviePath/ProjectDev.xcarchive -exportPath $ipaPath -exportOptionsPlist projectRelease.plist

mv $ipaPath/ProjectClient.ipa $ipaPath/Project_for_iOS_${version}_appstore.ipa

xcodebuild -exportArchive -archivePath $thearchviePath/ProjectDev.xcarchive -exportPath $ipaPath -exportOptionsPlist projectDev.plist

mv $ipaPath/ProjectClient.ipa $ipaPath/Project_for_iOS_${version}_appstore_test.ipa

echo "***************** export App ipa over *****************"

shell 实战脚本分析xcode崩溃日志

shortVersion=3.10.5
longVersion=03.10.5.0
logDirPath="/Users/liuzhimin/Library/Developer/Xcode/Products/com.inpor.Projectcloudios/${shortVersion}?(${longVersion})/Crashes/AppStore/"
outPutFile="/Users/liuzhimin/Desktop/CrashLog/CrashAnalyse.log"

#进度条函数
function ProgressBar {
    # Process data
    let _progress=(${1}*100/${2}*100)/100
    let _done=(${_progress}*4)/10
    let _left=40-$_done
    # Build progressbar string lengths
    _fill=$(printf "%${_done}s")
    _empty=$(printf "%${_left}s")
    printf "\r日志分析进度 : [${_fill// /#}${_empty// /-}] ${_progress}%%"
}

#数组是否包含函数
function array_containsSubString () {
    local seeking=$1; shift
    local in=1
    for element;
    do
        if [[ "$seeking" == *"$element"* ]]; then
            in=0
            break
        fi
    done
echo $in
}

# 客户端崩溃类型:

declare -a clientCrashArr=(
"Project: -[VNCViewController pinchView:]"
"Project: -[ConfMainViewController chatBtnTap:]"
"AudioToolbox: "
"UIKit:"
"MobileCoreServices"
)

# 系统崩溃类型:

declare -a libCrashArr=(
"libsystem_kernel.dylib: __pthread_kill"
"Project: -[WBPageInnerUIView drawRect:]"
"Project: -[MeetingRoomStateAdaptor UserAudioState:bID:bState:]"
"Project: -[VideoDeviceAdaptor writeVideoSample:buffer:bufferSize:]"
"AGXGLDriver:"
"Project: -[WBPageInnerUIView drawRect:]"
"GLEngine: gliPresentViewES_Exec"
"Project: ff_h264_decode_nal"
"Project: WBASELIB::WMsgQueue<HandlerMsg>::PushMsg(HandlerMsg*, unsigned int*)"
"Project: -[PopoverSheetViewController largeScreen:]"
"Project: std::__1::__tree<std::__1::__value_type<unsigned int, unsigned int>, std::__1::__map_value_compare<unsigned int, std::__1::__value_type<unsigned int, unsigned int>, std::__1::less<unsigned int>, true>, std::__1::allocator<std::__1::__value_type<unsigned int, unsigned int> > >::__node_insert_unique(std::__1::__tree_node<std::__1::__value_type<unsigned int, unsigned int>, void*>*)"
"Project: -[VideoCapture prepareWithWidth:andHeight:andFps:]"
"-[AVCtrl pauseRecvAllAudio:]"
"WNET_NETWORK::CSockWorkThread::ThreadProcEx()"
"IMGSGX554GLDriver"
"AGXMetalA10"
"[WhiteBoardViewController updateWBAccessMode]"
"[MultiWhiteBoardAdaptor setAccessMode:]"
)




cd ${logDirPath}
echo "📂 打开日志文件夹 进行扫描"

crashFoderPaths=`find ./ -type d -maxdepth 1 -mindepth 1`
rm -rf $outPutFile
echo "🚫 remove old analyse log"
sleep 0.5s

touch $outPutFile
echo "📃 创建新的日志准备写入"
sleep 0.5s

#崩溃的类型个数
crashKindCounts=`find ./ -type d -maxdepth 1 -mindepth 1 | wc -l`

#总的崩溃个数
allcrashCounts=0

for crashfolderPath in $crashFoderPaths
do
    #进入同一类崩溃统计的文件夹
    crashFolder=`basename $crashfolderPath`
    cd $crashFolder
    crashLogsCount=`find ./DistributionInfos/all/logs -type f -maxdepth 1 -mindepth 1 | wc -l`
    allcrashCounts=$(($allcrashCounts+$crashLogsCount))
    cd ..
done

#开始读取日志
logStart=0
logEnd=$(($allcrashCounts))

#客户端崩溃个数
clientCrashCounts=0
#服务器端崩溃个数
libCrashCounts=0
#客户端崩溃类型个数
clientCrashKindCounts=0
#服务器端崩溃类型个数
libCrashKindCounts=0
#类型冲突崩溃个数
errorCrashCounts=0
#未知崩溃个数
unknownCrashCounts=0

for crashfolderPath in $crashFoderPaths
do
    #进入同一类崩溃统计的文件夹
    crashFolder=`basename $crashfolderPath`
    cd $crashFolder

    crashName=`cat Info.json | jq '.DefaultName'`
    echo 崩溃名: ${crashName} >> $outPutFile

    crashLogsCount=`find ./DistributionInfos/all/logs -type f -maxdepth 1 -mindepth 1 | wc -l`
    echo 崩溃次数: ${crashLogsCount} >> $outPutFile

    iscrashTop=`cat ./DistributionInfos/all/Info.json | jq '.IsTopCrash'`
    echo 是否排行靠前崩溃: ${iscrashTop} >> $outPutFile

    #客户端崩溃
    isClient=$(array_containsSubString "$crashName" "${clientCrashArr[@]}")
    isLib=$(array_containsSubString "$crashName" "${libCrashArr[@]}")

    if test $isClient -eq 0 && test $isLib -eq 1; then
        clientCrashCounts=$(($clientCrashCounts+$crashLogsCount))
        clientCrashKindCounts=$(($clientCrashKindCounts+1))
        echo 崩溃类型: 客户端崩溃 >> $outPutFile
    fi


    if test $isLib -eq 0 && test $isClient -eq 1; then
        libCrashCounts=$(($libCrashCounts+$crashLogsCount))
        libCrashKindCounts=$(($libCrashKindCounts+1))
        echo 崩溃类型: 平台崩溃 >> $outPutFile
    fi

    if test $isClient -eq 0 && test $isLib -eq 0; then
        errorCrashCounts=$(($errorCrashCounts+$crashLogsCount))
        echo 崩溃类型: 类型冲突 >> $outPutFile
    fi


    if test $isLib -eq 1 && test $isClient -eq 1; then
        unknownCrashCounts=$(($unknownCrashCounts+$crashLogsCount))
        echo 崩溃类型: 未知崩溃 >> $outPutFile
    fi

    echo  ""  >> $outPutFile

    logStart=$(($logStart+$crashLogsCount))
    ProgressBar ${logStart} $logEnd

    cd ..
done

echo

echo 统计结果:
echo 所有崩溃总个数: $allcrashCounts
echo 崩溃类型总个数: $crashKindCounts
echo 统计结果:   >> $outPutFile
echo 所有崩溃总个数: $allcrashCounts   >> $outPutFile
echo 崩溃类型总个数: $crashKindCounts >> $outPutFile
persents=`echo "scale=4; ($clientCrashCounts * 100 / $allcrashCounts )" | bc | awk '{printf "%.4f", $0}'`
echo 客户端崩溃共 $clientCrashCounts 个,崩溃类型 $clientCrashKindCounts 个,占 $persents %
echo 客户端崩溃 $clientCrashCounts 个,崩溃类型 $clientCrashKindCounts 个,占 $persents %   >> $outPutFile
persents=`echo "scale=4; ($libCrashCounts * 100 / $allcrashCounts )" | bc | awk '{printf "%.4f", $0}'`
echo 平台崩溃共 $libCrashCounts 个,崩溃类型 $libCrashKindCounts 个,占 $persents %
echo 平台崩溃共 $libCrashCounts 个,崩溃类型 $libCrashKindCounts 个,占 $persents %   >> $outPutFile
persents=`echo "scale=4; ($errorCrashCounts * 100 / $allcrashCounts )" | bc | awk '{printf "%.4f", $0}'`
echo 冲突崩溃 $errorCrashCounts 个,占 $persents %
echo 冲突崩溃 $errorCrashCounts 个,占 $persents %   >> $outPutFile
persents=`echo "scale=4; ($unknownCrashCounts * 100 / $allcrashCounts )" | bc | awk '{printf "%.4f", $0}'`
echo 未知崩溃 $unknownCrashCounts 个,占 $persents %
echo 未知崩溃 $unknownCrashCounts 个,占 $persents %   >> $outPutFile

shell 实战符号化崩溃日志

#!/bin/bash

IFS=$'\n'

ARGS=("$@")

XCODE_DIR="/Applications/Xcode.app"
export DEVELOPER_DIR="${XCODE_DIR}/Contents/Developer"

XCODE_VERSION=$(defaults read /Applications/Xcode.app/Contents/version.plist CFBundleShortVersionString)

if [ ${XCODE_VERSION:0:1} == "6" ]; then
	CRASH="${XCODE_DIR}/Contents/SharedFrameworks/DTDeviceKitBase.framework/Versions/Current/Resources/symbolicatecrash"
else
	# test work on xcode7-8
	CRASH="${XCODE_DIR}/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash"
fi

function checkUUIDAndExec()
{
	LOG_PATH=$1
	APP_PATH=$2

	if [ $(echo "$APP_PATH" | grep "\.app\.dsym") ]; then
		# Find raw UUID when file is .app.dsym
		APP_UUID=$(dwarfdump --uuid $APP_PATH)
	elif [ $(echo "$APP_PATH" | grep "\.app") ]; then
		# Find raw UUID when file is .app
		# Find executable file name
		for i in $(ls "$APP_PATH"); do
			if [ $(echo "$i" | grep "\.") ]; then
				continue
			elif [ $(echo "$i" | grep "PkgInfo") ]; then
				continue
			elif [ $(echo "$i" | grep "_CodeSignature") ]; then
				continue
			else
				EXEC_NAME=$i
			fi
		done
		if [ "$EXEC_NAME"x = x ]; then
			echo "App name not found"
		fi
		APP_UUID=$(dwarfdump --uuid "$APP_PATH/$EXEC_NAME")
	else
		echo "App path $APP_PATH is not valid"
		return
	fi

	# Extract UUID from raw data
	for i in $(echo "$APP_UUID" | grep -Eo "UUID: [0-9a-fA-F\-]+ "); do
		if [[ "$i" = "UUID:" ]]; then
			continue
		else
			# Execute if lowercase UUID is found in crash log
			UUID=$(echo "${i//-/}" | tr 'A-F' 'a-f' | awk '{print $2}')
			if [[ $(grep "$UUID" "$LOG_PATH") ]]; then
				$CRASH -v $ARGS
				break
			else
				echo "UUID is not matched"
			fi
		fi
	done
}

checkUUIDAndExec $1 $2

最近的文章

ffmpegMetalPlayer(OSX)教程一

简介这一份教程是关于如何使用最新的 FFmpeg 3.2.4 进行音视频的编解码,以及如何使用 metal 对解码之后的帧数据进行渲染. 感觉现在的 ffmpeg 教程都是基于 2.x 的所以就自己鼓捣了一下,希望和大家一起讨论交流共同进步. 本教程的 github 源码 (运行环境 OSX)也会跟随本教程持续更新.因为作者有全职工作所以不能保证更新进度望大家理解. 本教程也参考了 kxMovie 感谢作者.音视频基础介绍首先,大家需要有一定的基础知识,对于音视频其实大家都知道所谓的视频就...…

OSX继续阅读
更早的文章

fmpeg参数中文详细解释

A 通用选项-L | license-h 帮助-fromats 显示可用的格式,编解码的,协议的...-f fmt 强迫采用格式fmt-I filename 输入文件-y 覆盖输出文件-t duration 设置纪录时间 hh:mm:ss[.xxx]格式的记录时间也支持-ss position 搜索到指定的时间 [-]hh:mm:ss[.xxx]的格式也支持-title string 设置标题-author string 设置作者-copyright string 设置版权-comment...…

av继续阅读