常用bash脚本

1. 简介

本文介绍了一些常用事务处理的脚本,我这些脚本被放置在~/tools/bash目录,并在~/tools/tools.sh中定义了相关的aliastools.sh文件在~/.bashrc中加载进来。其中有些命令在git-bashLinux下都适用的。

2. ~/.bashrc

通常在~/.bashrc中定义一些环境变量和一些专用别名。

#!/bin/bash

export MYTOOLS=$HOME/tools
export MYBINS=$HOME/bin
export PATH=$MYBINS:$PATH
export LANG=zh_CN.UTF-8

# Some alias defined in /etc/baseprofile
alias cdd='cd /c/Users/$USER/Desktop'

test -f $MYBINS/bin.sh && . $MYBINS/bin.sh
test -f $MYTOOLS/tools.sh && . $MYTOOLS/tools.sh

3. $MYTOOLS/tools.sh

该脚本用于定义常用脚本的别名以方便调用。

#!/bin/bash

alias cd=". $MYTOOLS/bash/cd.sh"
alias agg=". $MYTOOLS/bash/agg.sh"
alias cgg=". $MYTOOLS/bash/cgg.sh"
alias gg=". $MYTOOLS/bash/gg.sh"
alias kgg=". $MYTOOLS/bash/kgg.sh"
alias grw=". $MYTOOLS/bash/grw.sh"
alias gr=". $MYTOOLS/bash/gr.sh"
alias grv=". $MYTOOLS/bash/grv.sh"
alias del="$MYTOOLS/bash/del.sh"
alias ndel="$MYTOOLS/bash/ndel.sh"
alias pbin="$MYTOOLS/bash/pbin.sh"

alias jd=". $MYTOOLS/bash/jd.sh"
alias aasm=". $MYTOOLS/bash/aasm.sh"
alias abin=". $MYTOOLS/bash/abin.sh"
alias ocd="$MYTOOLS/bash/ocd.sh"

func_pushd() { \pushd $@ > /dev/null; }
alias pushd='func_pushd'
alias cdirs=". $MYTOOLS/bash/cdirs.sh"
alias dirs='dirs -v'
alias vi='vim'
alias ll='\ls -l --color=tty'
alias l.='\ls -d .* --color=tty'
alias cp='\cp -i'
alias rm='\rm -i'
alias mv='\mv -i'

4. 通用脚本

这些脚本被放置在$MYTOOLS/bash目录下。

4.1 cd.sh

该脚本实现了将Windows格式路径修改为Linux格式路径,然后再使用cd命令进入对应的目录。

#!/bin/bash

WIN_PATH="$1"
LINUX_PATH=${WIN_PATH//\\//}
# git-bash
PREFIX=/
# MobaXterm
#PREFIX=/drives/
# wsl
#PREFIX=/mnt/
# VMware-Ubuntu
#PREFIX=/mnt/windows/

if [[ $LINUX_PATH == *:* ]]; then
	DISK_NAME=$(echo ${LINUX_PATH%:*} | tr 'A-Z' 'a-z')
	LINUX_PATH=${LINUX_PATH#*:}
	LINUX_PATH=$PREFIX${DISK_NAME}${LINUX_PATH/:/}
fi

if [ -z "$LINUX_PATH" ]; then
	\cd
else
	\cd "$LINUX_PATH"
fi
unset DISK_NAME
unset LINUX_PATH
unset WIN_PATH
unset PREFIX

使用alias重新定义cd命令,使用的时候对于Linux格式的命令和之前的一样,对于Windows格式的命令需要将路径使用"'包括起来。

# 定义别名,”.“表示在当前bash环境下执行该脚本,不要另外启动一个bash环境
$ alias cd=". ~/tools/bash/cd.sh"
# Linux格式的路径,不需要加引号
$ cd /D/apps_no_install/Git
$ cd //192.168.1.31/共享文件
# Windows格式的路径,需要加引号
$ cd 'D:\apps_no_install\Git_readme'
$ cd '\\192.168.1.31\共享文件'

4.2 bin_update.sh

该脚本用于将windows系统中安装的一些程序汇总到一个目录,避免PATH中路径过多,该文件需要根据实际情况进行增删。$MYBIN是我在~/.bashrc中定义的环境变量,其值为~/binEXE_PATH应根据具体环境决定,比如c盘在git-bash中对应/c/MobaXterm中对应/drivers/c/wsl中对应/mnt/c/,另外在wsl中盘符仅支持小写。

#!/bin/bash

mkdir -p $MYBINS

func_link()
{
	NUM=${#FILEOLD[@]}
	for ((i=0; i<NUM; i++)); do
		echo -e "#!/bin/bash\nPATH=\"$EXE_PATH\":$""PATH \"$EXE_PATH/$PREFIXOLD${FILEOLD[$i]}$SUFFIXOLD\" \"$""@\"" > "$MYBINS/$PREFIXNEW${FILENEW[$i]}$SUFFIXNEW"
		if [ $? -ne 0 ]; then
			echo "$EXE_PATH/$PREFIXOLD${FILEOLD[$i]}$SUFFIXOLD"
		fi
		chmod +x "$MYBINS/$PREFIXNEW${FILENEW[$i]}$SUFFIXNEW"
	done
}

EXE_PATH=/d/Keil_v5_40/UV4
PREFIXOLD=""
PREFIXNEW=""
SUFFIXOLD=".exe"
SUFFIXNEW=""
FILEOLD=(uv4)
FILENEW=(uv4)
#func_link

EXE_PATH=/d/Keil_v5_40/UV4
PREFIXOLD=""
PREFIXNEW=""
SUFFIXOLD=".com"
SUFFIXNEW=""
FILEOLD=(uVision)
FILENEW=(uVision)
#func_link

EXE_PATH=/d/Keil_v5_40/ARM/ARMCLANG/bin
PREFIXOLD=""
PREFIXNEW=""
SUFFIXOLD=".exe"
SUFFIXNEW=""
FILEOLD=(armclang clang-format armar armasm armlink fromelf)
FILENEW=(armclang clang-format armar armasm armlink fromelf)
#func_link

EXE_PATH=/d/apps_no_install/csky-elfabiv2-tools-mingw-minilibc-20210423/bin
PREFIXOLD=csky-elfabiv2-
PREFIXNEW=csky-abiv2-elf-
SUFFIXOLD=".exe"
SUFFIXNEW=""
FILEOLD=(ar as g++ gcc gcov gdb ld nm objcopy objdump readelf size strip strings)
FILENEW=(ar as g++ gcc gcov gdb ld nm objcopy objdump readelf size strip strings)
#func_link

EXE_PATH=/d/apps_no_install/arm-gnu-toolchain-13.2.Rel1-mingw-w64-i686-arm-none-eabi/bin
PREFIXOLD=arm-none-eabi-
PREFIXNEW=arm-none-eabi-
SUFFIXOLD=".exe"
SUFFIXNEW=""
FILEOLD=(ar as g++ gcc gcov gdb ld nm objcopy objdump readelf size strip strings)
FILENEW=(ar as g++ gcc gcov gdb ld nm objcopy objdump readelf size strip strings)
#func_link

EXE_PATH=/d/Qt/Qt5.11.2/Tools/mingw530_32/bin
PREFIXOLD=""
PREFIXNEW=""
SUFFIXOLD=".exe"
SUFFIXNEW=""
FILEOLD=(ar as g++ gcc gcov gdb ld nm objcopy objdump readelf size strip strings windres)
FILENEW=(ar as g++ gcc gcov gdb ld nm objcopy objdump readelf size strip strings windres)
#func_link

EXE_PATH=/d/Qt/Qt5.11.2/5.11.2/mingw53_32/bin
PREFIXOLD=""
PREFIXNEW=""
SUFFIXOLD=".exe"
SUFFIXNEW=""
FILEOLD=(windeployqt)
FILENEW=(windeployqt)
#func_link


EXE_PATH="/d/Program Files/CMake/bin"
PREFIXOLD=""
PREFIXNEW=""
SUFFIXOLD=".exe"
SUFFIXNEW=""
FILEOLD=(cmake-gui cmake)
FILENEW=(cmake-gui cmake)
#func_link

EXE_PATH="/d/apps_no_install/OpenOCD-20231002-0.12.0/bin"
PREFIXOLD=""
PREFIXNEW=""
SUFFIXOLD=".exe"
SUFFIXNEW=""
FILEOLD=(openocd)
FILENEW=(openocd)
#func_link

EXE_PATH="/d/Program Files/Pandoc"
PREFIXOLD=""
PREFIXNEW=""
SUFFIXOLD=".exe"
SUFFIXNEW=""
FILEOLD=(pandoc)
FILENEW=(pandoc)
#func_link

EXE_PATH="/mnt/d/apps_no_install/Beyond Compare"
PREFIXOLD=""
PREFIXNEW=""
SUFFIXOLD=".exe"
SUFFIXNEW=""
FILEOLD=(BCompare)
FILENEW=(_BCompare)
func_link

EXE_PATH="/mnt/d/Program Files/Notepad++"
PREFIXOLD=""
PREFIXNEW=""
SUFFIXOLD=".exe"
SUFFIXNEW=""
FILEOLD=(notepad++)
FILENEW=(_notepad++)
func_link

EXE_PATH="/c/Users/xflm/tools/gcc/bin"
PREFIXOLD=""
PREFIXNEW=""
SUFFIXOLD=".exe"
SUFFIXNEW=""
FILEOLD=(float2hex hex2float hex2u32)
FILENEW=(float2hex hex2float hex2u32)
#func_link


该命令不常用,故不需要定义alias,这里将PATH新增了可执行文件的路径,因为可执行文件可能会调用其所在目录里的动态库。

$ ~/tools/bash/bin_update.sh
$ ls bin
ar  arm-none-eabi-ar ...
$ cat ~/bin/ar
#!/bin/bash
PATH="/d/Qt/Qt5.11.2/Tools/mingw530_32/bin":/c/Users/xflm/tools/gcc/bin:/c/Users/xflm/bin:/mingw64/bin:/usr/bin:/c/Users/xflm/bin:/d/project/apps_no_install/Python37/Scripts:/d/project/apps_no_install/Python37:/c/Windows/system32:/c/Windows:/c/Windows/System32/Wbem:/c/Windows/System32/WindowsPowerShell/v1.0 "/d/Qt/Qt5.11.2/Tools/mingw530_32/bin/ar.exe" "$@"

4.3 agg.sh

该脚本实现了对arm-none-eabi-gdb的调用,主要是开启了gdb的命令记录功能,也即退出gdb后,gdb会将历史命令写入到文件中,等下次启动gdb后自动读取进来。$MYTOOLS是我定义在~/.bashrc的一个环境变量,其值为~/toolscommon.gdb是个gdb脚本文件,下文会展示。

#!/bin/bash

if [ -f .gdb_history ]; then
	tmp_GDB_HISTORY=.gdb_history
else
	tmp_GDB_HISTORY=$MYHOME/.gdb_history
fi

arm-none-eabi-gdb \
-q "$@" \
-ex "set history filename $tmp_GDB_HISTORY" \
-x  $MYTOOLS/gdb/arm/init.gdb

unset tmp_GDB_HISTORY

init.gdb的内容如下。

# 关闭退出再确认功能
set confirm off
# 关闭分页显示功能
set pagination off
# 开启历史记录保存功能
set history save on
# 开启打印格式化
set print pretty

使用alias定义agg命令,以后就可以使用agg替代arm-none-eabi-gdb

$ alias agg=". ~/tools/bash/agg.sh"

4.4 cgg.sh

该脚本功能和agg.sh相似。

#!/bin/bash

if [ -f .gdb_history ]; then
	tmp_GDB_HISTORY=.gdb_history
else
	tmp_GDB_HISTORY=$MYHOME/.gdb_history
fi

csky-abiv2-elf-gdb \
-q "$@" \
-ex "set history filename $tmp_GDB_HISTORY" \
-x  $MYTOOLS/gdb/csky/init.gdb

unset tmp_GDB_HISTORY

4.5 gg.sh

该脚本功能和agg.sh相似。

#!/bin/bash

if [ -f .gdb_history ]; then
	tmp_GDB_HISTORY=.gdb_history
else
	tmp_GDB_HISTORY=$MYHOME/.gdb_history
fi

gdb \
-q "$@" \
-ex "set history filename $tmp_GDB_HISTORY" \
-x  $MYTOOLS/gdb/host/init.gdb

unset tmp_GDB_HISTORY

4.6 kgg.sh

有时候gdb运行卡住了,或则我们想退出gdb但是不想打断cpu的运行,则我们可以通过kill命令结束gdb进程,搜索中限定了$USER故不会介素别人开启的gdb进程。

#!/bin/bash

tmp_GDBPID=$(ps -ef | grep -w gdb | grep $USER | grep -v grep | awk '{print $2}')

if [ -z "$tmp_GDBPID" ]; then
	echo "kgg: No gdb process is running"
	return 1
fi

kill -9 $tmp_GDBPID

unset tmp_GDBPID

4.7 grw.sh

该脚本主要是用于搜索当前目录及子目录中.c``.h``.s``.S文件中的word,比如搜索函数名或变量名啥的。

#!/bin/bash

if [ $# -ne 1 ]; then
	echo "grw [content]"
	return 1
fi

echo -e "\033[35m====================\033[0m"
\grep $1 -nrw --color=auto --include=*\.[chsS] --include=[Mm]akefile
echo -e "\033[35m====================\033[0m"

使用alias定义grw命令。

$ alias grw=". ~/tools/bash/grw.sh"
# 如在某工程目录下使用,搜索到的内容会有颜色显示的
$ grw main
====================
gpio_ex2_toggle/src/gpio_ex2_toggle.c:28:int main(void)
====================

4.8 gr.sh

该脚本和grw.sh类似,只是grep的参数中少了w,也即允许匹配word内部的内容。

#!/bin/bash

if [ $# -ne 1 ]; then
	echo "gr [content]"
	return 1
fi

echo -e "\033[35m====================\033[0m"
\grep $1 -nr --color=auto --include=*\.[chsS] --include=[Mm]akefile
echo -e "\033[35m====================\033[0m"

4.9 grv.sh

该脚本用于快速打开grep搜索的内容,grep搜索的结果中包含了行号,vim可以直接定位到该行号。

#!/bin/bash

if [ $# -eq 0 ]; then
	echo "grv [content]"
	return 1 
else
	for i in $*; do
		tmp_FILE+=$(echo $i | awk -F ':' '{print $1" +"$2" "}')
	done
	vim $tmp_FILE -On
fi

unset tmp_FILE

使用alias定义grv命令。

$ alias grv=". ~/tools/bash/grv.sh"
# 如在某工程目录下将grw搜索的内容,通过grv查看,通常下面这一串,在git-bash中双击就选中了,选中后右键一次表示复制,再右键一次表示粘贴,十分方便
$ grv gpio_ex2_toggle/src/gpio_ex2_toggle.c:28:int 

4.10 del.sh

该脚本用于模拟一个简单的文件回收站,使用该脚本进行文件删除时,该脚本会将文件剪切到~/null目录,未来可通过ndel.sh进行恢复,文件/目录等都可以被回收。

#!/bin/bash

RECYCLE_DIR=~/null
RECYCLE_LOG=.log

if [ $# -eq 0 ]; then
	if [ ! -d $RECYCLE_DIR ]; then
		echo "You have deleted nothing."
		exit 0
	fi

	LAST_DIR=$(\ls $RECYCLE_DIR | tail -n 1)

	if [ -z "$LAST_DIR" ]; then
		echo "You have deleted nothing."
		rm -rf $RECYCLE_DIR
		exit 0
	fi

	cat $RECYCLE_DIR/$LAST_DIR/$RECYCLE_LOG
	exit 0
fi

NEW_DIR=$RECYCLE_DIR"/"$(date +%F)
NEW_LOG=$NEW_DIR/$RECYCLE_LOG
[ -d $NEW_DIR ] || mkdir -p $NEW_DIR
NEW_TIME=$(date +%H%m%M%S)
LOG=""

for DEL_FILE in $@; do
	REC_FILE=$NEW_DIR/$NEW_TIME"."$(basename $DEL_FILE)
	mv $DEL_FILE $REC_FILE

	if [ $? -eq 0 ]; then
		if [[ "$DEL_FILE" == /* ]]; then
			echo -e "$REC_FILE $DEL_FILE" >> $NEW_LOG
		else
			echo -e "$REC_FILE $PWD/$DEL_FILE" >> $NEW_LOG
		fi
	else
		exit 0
	fi
done

使用时通过alias定义一个del命令。

# 定义别名,脚本中变量比较多,不在当前bash环境执行
$ alias del=~/tools/bash/del.sh
# 新建目录,并创建个测试文件
$ mkdir aa && touch aa/1.txt
# 删除文件
$ del aa/1.txt
# 查看删除日志
$ del
/c/Users/xflm/null/2024-01-17/11015156.1.txt /d/apps_no_install/aa/1.txt
# 查看回收站的内容
$ ls ~/null/*/*
/c/Users/xflm/null/2024-01-17/11015156.1.txt

4.11 ndel.sh

该脚本用于恢复del删除的文件。

#!/bin/bash

RECYCLE_DIR=~/null
RECYCLE_LOG=.log

if [ $# -eq 0 ]; then
	echo "Usage: ndel [deleted file below]"
	ls $RECYCLE_DIR/*/*
	exit 0
fi

for FILE in $@; do
	if [ -f $FILE ]; then
		FILE_DIR=$(dirname $FILE)
		FILE_NAME=$(basename $FILE)
	else
		FILE_NAME=${FILE##*/}

		if [ -z "$FILE_NAME" ]; then
			LOG1=${FILE%/*}
			FILE_NAME=${LOG1##*/}
			FILE_DIR=${LOG1%/*}
		else
			FILE_DIR=${FILE%/*}
		fi
	fi

	LOG1=$(grep -n "/$FILE_NAME\b" $FILE_DIR/$RECYCLE_LOG)

	if [ -z "$LOG1" ]; then
		echo "No this file delete log."
		exit 1
	fi

	LINE=${LOG1%%:*}
	LOG2=${LOG1#*:}
	RECYCLE_FILE=${LOG2% *}
	ORIGINAL_FILE=${LOG2#* }

	if [ -e "$ORIGINAL_FILE" ]; then
		echo "$ORIGINAL_FILE: The file is exist, cannot recovery."
		exit 1
	fi

	sed -i "$LINE"d $FILE_DIR/$RECYCLE_LOG
	
	if [ ! -e $FILE ]; then
		echo $FILE: Not exist.
		exit 1
	fi
		
	mv $LOG2

	if [ ! -s $FILE_DIR/$RECYCLE_LOG ]; then
		rm -f $FILE_DIR/$RECYCLE_LOG

		if [ -z "$(\ls $FILE_DIR)" ]; then
			rm -rf $FILE_DIR
		else
			echo $FILE_DIR: Dir has files, but log is empty.
		fi
	fi
done

使用时通过alias定义一个ndel命令。

# 定义别名,脚本中变量比较多,不在当前bash环境执行
$ alias ndel=~/tools/bash/ndel.sh
# 查看删除日志
$ ndel
Usage: ndel [deleted file below]
/c/Users/xflm/null/2024-01-17/11015156.1.txt
# 恢复被删除的内容
$ ndel /c/Users/xflm/null/2024-01-17/11015156.1.txt

4.12 pbin.sh

封装了一下od命令用于查看bin文件内容。

#!/bin/bash

func_help()
{
	cat << EOF
Usage: pbin [options] file
  -h              Print this usage
  -f FileName
  -s StartAddress Default 0x0
  -p PrintAddress Default StartAddress
  -t PrintType    Default x4
       a          named character, ignoring high-order bit
       c          printable character or backslash escape
       d[SIZE]    signed decimal, SIZE bytes per integer
       f[SIZE]    floating point, SIZE bytes per integer
       o[SIZE]    octal, SIZE bytes per integer
       u[SIZE]    unsigned decimal, SIZE bytes per integer
       x[SIZE]    hexadecimal, SIZE bytes per integer
  -w BytesPerLine Defult 16
  -n PrintBytes   Default 16
EOF
}

START_ADDR=0x0
PRINT_ADDR=""
PRINT_TYPE=x4
LINE_BYTES=16
PRINT_BYTES=16

while getopts "hf:s:p:t:w:n:" optname; do
	case "$optname" in
		"h")
			func_help
			exit
		;;
		"f")
			BIN_FILE=$OPTARG
		;;
		"s")
			START_ADDR=$OPTARG
		;;

		"p")
			PRINT_ADDR=$OPTARG
		;;
		"t")
			PRINT_TYPE=$OPTARG
		;;
		"w")
			LINE_BYTES=$OPTARG
		;;
		"n")
			PRINT_BYTES=$OPTARG
		;;
		":")
			echo No argument value for option $OPTARG
			exit -1
		;;
		"?")
			echo Unknow option $OPTARG
			exit -1
		;;
	esac
done

if [ -z "$BIN_FILE" ]; then
	echo Error: no bin file. Use -h for help.
	exit -1
fi

if [ -z "$PRINT_ADDR" ]; then
	PRINT_ADDR=$START_ADDR
fi

# Must be converted to hexadecimal, otherwise will be set to base 8.
PRINT_ADDR=$(printf "0x%08x" $PRINT_ADDR)
START_ADDR=$(printf "0x%08x" $START_ADDR)
SKIP_ADDR=$(printf "0x%08x" $((PRINT_ADDR-START_ADDR)))

od -t $PRINT_TYPE -Ax -v -w$LINE_BYTES --traditional -N$PRINT_BYTES $BIN_FILE +$SKIP_ADDR +$PRINT_ADDR

使用示例。

# 默认查看bin文件的前4个words
$ pbin -f test.bin
000000 (000000) 6f6e6e49 74655320 55207075 736e696e
000010 (000010)
# 将test.bin映射到0x08000000,查看0x08000010开始的24个字节的数据,使用16进制显示,每行显示8个字节
$ pbin -f test.bin -s 0x08000000 -p 0x08000010 -n 24 -t x1 -w 8
000010 (8000010) 74 61 6c 6c 20 4c 6f 67
000018 (8000018) 20 28 62 29 20 36 34 2d
000020 (8000020) 62 69 74 00 00 00 00 00
000028 (8000028)

4.13 cdirs.sh

Shell中有pushdpopd两个命令,前者将当前工作路径压入队列,后者从队列中取出一个路径,并跳转过去。还有个dirs命令,用于显示这个队列中的内容,此处基于dirs做了一个路径选择的交互式脚本,可用于在多个路径之间跳转,该脚本还提供了历史路径的保存与恢复功能。

#!/bin/bash

\dirs -v
echo "<s>:Save; <l>:Load; <c>:Clear; <d>:Delete"
read -p "cd: " _PATH_NUM

if [[ ! -z "$_PATH_NUM" ]]; then
	case $_PATH_NUM in
		"")
		;;

		s)
			echo "Save history to file"
			\dirs -p | sort -u | sed 's/^/\\pushd -n /g' > ~/.cdirs_history
		;;

		l)
			echo "Load form file"
			[[ -e ~/.cdirs_history ]] && . ~/.cdirs_history > /dev/null
		;;

		c)
			echo "Clear all entry"
			\dirs -c
		;;

		d*)
			_PATH_NUM=$(echo $_PATH_NUM | sed 's/d\s*//g')
			echo "Delete "$_PATH_NUM
			\popd +$_PATH_NUM > /dev/null
		;;

		*) \pushd +$_PATH_NUM > /dev/null
		;;
			
	esac
fi

unset _PATH_NUM

5. 专用脚本

5.1 jd.sh

使用JLinkGdbServerCL命令行程序开启gdbserver。

#!/bin/bash

tmp_JLinkGDBServer="D:/Program Files (x86)/SEGGER/JLink_V622/JLinkGDBServerCL.exe"

"$tmp_JLinkGDBServer" \
-silent \
-nologtofile \
-device Cortex-M3 \
-if SWD \
-speed auto \
-noir \
-noLocalhostOnly \
-select usb \
-endian little \
-port 1027 \
-SWOPort 2332 \
-noreset \
-nohalt \
"$@"

# User can use cmd below to change the script settings:
# -nosilent
# -log [file]
# -port [port]
# -SWOPort [port]
# -select IP=[IP:Port]

unset tmp_JLinkGDBServer

5.2 aasm.sh

使用Keil工具链中的fromelf程序生成反汇编文件。

#!/bin/bash

func_help()
{
	echo Uasge: aasm *.axf *.asm
}

if [ $# -ne 2 ]; then
	func_help
else
	fromelf -a -c --text --output $2 $1
fi

5.3 abin.sh

使用Keil工具链中的fromelf程序生成bin文件。

#!/bin/bash

func_help()
{
	echo Uasge: abin *.axf *.bin
}

if [ $# -ne 2 ]; then
	func_help
else
	fromelf --bin --output $2 $1
fi

5.4 ocd.sh

使用openocd工具创建连接。

#!/bin/bash

cd /d/apps_no_install/OpenOCD-20231002-0.12.0/bin
./openocd -f interface/stlink-dap.cfg -f target/stm32h7x.cfg```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值