Difference between revisions of "Shell"
m (Add S3 upload script.) |
m (Amended script to show set of files changes across a series of commits) |
||
Line 139: | Line 139: | ||
exit #? | exit #? | ||
</pre> | </pre> | ||
+ | |||
+ | <!-- | ||
+ | |||
+ | #!/bin/bash | ||
+ | |||
+ | CMD_GIT=/usr/bin/git | ||
+ | |||
+ | # Changed file filter, may differ on various work stations: | ||
+ | MATCH_CHANGED_FILE_LINE=":100644" | ||
+ | |||
+ | function usage() | ||
+ | { | ||
+ | echo "call $0 with:" | ||
+ | echo | ||
+ | echo " $ $0 <count> [-u|-d]" | ||
+ | echo " $ $0 <count> [--show-dirs --make-dirs] <dest_dit> # <- both long options required here" | ||
+ | echo " $ $0 <count> -c <dest_dir>" | ||
+ | echo | ||
+ | echo "count . . . count of commits to review from tip of git branch" | ||
+ | echo "-u . . . optionally summarize file changes to list of unique files changed" | ||
+ | } | ||
+ | |||
+ | function shows_changed_files_per_commit() | ||
+ | { | ||
+ | echo "function f1 starting" | ||
+ | # $CMD_GIT log --oneline | head | cut -d " " -f 1 | ||
+ | # echo | ||
+ | |||
+ | hashes=`$CMD_GIT log --oneline | head -n ${1} | cut -d " " -f 1` | ||
+ | echo "In $PWD found git commit hashes:" | ||
+ | echo " " $hashes | ||
+ | |||
+ | #echo "Files changed between commit pairs youngest pairings to oldest: | ||
+ | #for hash in $hashes; do echo "Files changed in git commit:"; git diff-tree -r $hash; echo; done | ||
+ | for hash in $hashes | ||
+ | do echo "Files changed in git commit:" | ||
+ | git log -1 --oneline $hash | ||
+ | git diff-tree -r $hash | ||
+ | echo | ||
+ | done | ||
+ | } | ||
+ | |||
+ | function show_unique_changed_files_across_all_commits() | ||
+ | { | ||
+ | shows_changed_files_per_commit ${1} | \ | ||
+ | grep ${MATCH_CHANGED_FILE_LINE} | cut -f 2 | sort --unique | ||
+ | } | ||
+ | |||
+ | # This function expects: | ||
+ | # $1 . . . count of commits to check, starting from branch tip | ||
+ | |||
+ | function show_dirs_per_changed_file() | ||
+ | { | ||
+ | echo "f3 called with $# arguments," | ||
+ | |||
+ | shows_changed_files_per_commit ${1} | \ | ||
+ | grep ${MATCH_CHANGED_FILE_LINE} | cut -f 2 | sort --unique | ||
+ | } | ||
+ | |||
+ | # This function expects: | ||
+ | # $1 . . . count of commits to check, starting from branch tip | ||
+ | # $2 . . . path relative or absolute in which to create copies of paths to each changed file | ||
+ | |||
+ | function recreate_directory_paths() | ||
+ | { | ||
+ | i=1 | ||
+ | # for hash in $hashes; do echo "("$i")" $hash; (( i++ )); done | ||
+ | |||
+ | # awk -F "/" ' { print NF-1 } ' # . . . provides count of dirs | ||
+ | # dirs=`sed 's/\//\ /g'` # . . . provides dirnames and filename per path | ||
+ | |||
+ | echo "f4 called with $# arguments," | ||
+ | echo "caller wants to recreate dir structures in '${2}'" | ||
+ | |||
+ | files=`shows_changed_files_per_commit ${1} | \ | ||
+ | grep ${MATCH_CHANGED_FILE_LINE} | cut -f 2 | sort --unique` | ||
+ | |||
+ | # TODO [ ] find a way to remove just the filename, then call `mkdir -pv one_or_more_dirs` | ||
+ | # echo ${files} | ||
+ | for file in ${files}; do | ||
+ | dir_count=`echo $file | awk -F "/" ' { print NF-1 } '` | ||
+ | if [ $dir_count -gt 0 ]; then | ||
+ | # dirs=`sed 's/\//\ /g'` | ||
+ | dirs=`echo ${file} | rev | sed 's/\//\ /' | rev | cut -d " " -f 1` | ||
+ | echo "(d) ${file} has dirs ${dirs}" | ||
+ | echo "(c) creating ${2}/${dirs} . . ." | ||
+ | mkdir -pv ${2}/${dirs} | ||
+ | (( i++ )) | ||
+ | fi | ||
+ | done | ||
+ | } | ||
+ | |||
+ | # This function expects: | ||
+ | # $1 . . . count of commits to check, starting from branch tip | ||
+ | # $2 . . . path relative or absolute in which to create copies of paths to each changed file | ||
+ | |||
+ | function copy_relpaths_and_file() | ||
+ | { | ||
+ | echo "f5 called with $# arguments," | ||
+ | echo "caller wants to copy relative paths and changed files to '${2}'" | ||
+ | commit_count=$1 | ||
+ | scratch_dir=$2 | ||
+ | |||
+ | files=`shows_changed_files_per_commit $1 | \ | ||
+ | grep ${MATCH_CHANGED_FILE_LINE} | cut -f 2 | sort --unique` | ||
+ | |||
+ | for file in $files; do | ||
+ | dir_count=`echo $file | awk -F "/" ' { print NF-1 } '` | ||
+ | if [ $dir_count -gt 0 ]; then | ||
+ | # dirs=`sed 's/\//\ /g'` | ||
+ | dirs=`echo $file | rev | sed 's/\//\ /' | rev | cut -d " " -f 1` | ||
+ | echo "(d) $file has dirs $dirs" | ||
+ | echo "(c) creating $scratch_dir/$dirs . . ." | ||
+ | mkdir -pv $scratch_dir/$dirs | ||
+ | |||
+ | cp -pv $file $scratch_dir/$dirs | ||
+ | |||
+ | (( i++ )) | ||
+ | else | ||
+ | cp -pv $file $scratch_dir//$file | ||
+ | fi | ||
+ | done | ||
+ | } | ||
+ | |||
+ | # | ||
+ | # - SECTION - entry point akin to int main | ||
+ | # | ||
+ | |||
+ | echo "2024-01-31 git diff-tree helper script in progress . . ." | ||
+ | echo "got $# arguments, arg one single quoted is '$1'" | ||
+ | echo | ||
+ | |||
+ | if [ $# -lt 1 ] ; then | ||
+ | usage | ||
+ | elif [ $# -eq 1 ] ; then | ||
+ | shows_changed_files_per_commit ${1} | ||
+ | elif [ ${2} == "-u" ] ; then | ||
+ | show_unique_changed_files_across_all_commits ${1} | ||
+ | elif [ ${2} == "-d" ] ; then | ||
+ | show_dirs_per_changed_file ${1} | ||
+ | elif [[ ${2} == "--show-dirs" && ${3} == "--make-dirs" ]] ; then | ||
+ | recreate_directory_paths ${1} ${4} | ||
+ | elif [ ${2} == "-c" ] ; then | ||
+ | copy_relpaths_and_file ${1} ${3} | ||
+ | else | ||
+ | usage | ||
+ | fi | ||
+ | |||
+ | |||
+ | exit $? | ||
+ | --> | ||
<!-- odne komentar --> | <!-- odne komentar --> |
Revision as of 23:07, 19 September 2025
Shell Scripting
^ OVERVIEW
This local page for Bash shell scripts and notes on shell scripting.
^ Bash Built-in Variables
Some links to useful articles discussing `bash` built-in variables:
- https://avpres.net/Bash/builtin_shell_variables
- https://www.gnu.org/software/bash/manual/html_node/Bash-Variables.html
Bash's built-in variables with short names, as listed in Kernigan and Ritchie's "Unix Programming" book and at the first linked article above:
$0 The first element passed to the shell is the command name. $n The nth argument passed on the command line. If n ≥ 10, then the syntax must be ${n}. $* All the arguments on the command line. The values are separated by the first character in the shell variable IFS: (${1} … ${n}). See also: the IFS entry in Other Shell Variables. $@ All the arguments on the command line. The values are individually quoted: ("${1}" … "${n}"). $# The number of command-line arguments. $? The exit value of the last executed command. $_ The last argument of the previous command. $! The process ID of the most recent background process.
^ Rename Badly Named Files
How to produce a usable filename which contains <ESC> characters, and to rename that badly named file:
$ ls -i 9704871 $'\033\033' 9703029 CMakeLists.txt 10899590 dts 9708845 samples $ ls -q `find . -inum 9704871` './'$'\033\033' $ mv './'$'\033\033' betterfilename
^ Git Diff-tree Helper Script
A helper script for calling `git diff-tree`, which can be used to determine at which project commit one or more files have changed:
#!/bin/bash CMD_GIT=/usr/bin/git $CMD_GIT log --oneline | head | cut -d " " -f 1 echo "2024-01-31 git diff-tree helper script in progress . . ." echo "got $# arguments, arg one single quoted is '$1'" hashes=`$CMD_GIT log --oneline | head -n ${1} | cut -d " " -f 1` echo "In $PWD found git commit hashes:" echo " " $hashes #i=1 #for hash in $hashes; do echo "("$i")" $hash; (( i++ )); done #echo "Files changed between commit pairs youngest pairings to oldest: #for hash in $hashes; do echo "Files changed in git commit:"; git diff-tree -r $hash; echo; done for hash in $hashes do echo "Files changed in git commit:" git log -1 --oneline $hash git diff-tree -r $hash echo done echo "done" exit 0
Script to test compilation of series of git commits:
#!/bin/bash CMD_GIT=/usr/bin/git VETTED_COMMITS_FILE="branch-commit-vetting-report.txt" current_branch="NOT_SET" hashes="NOT_SET" function usage() { echo "How to use vet-branch.sh:": echo echo " $ vet-branches.sh n" echo echo "Argument 'n' is a number of commits to test in current git branch." echo } # # script starting point, akin to int main # echo "$0: starting" if [ $# -lt 1 ] then echo "$0 called with too few arguments!" usage exit -1 fi current_branch=`$CMD_GIT branch --show-current` hashes=`$CMD_GIT log --oneline | head -n $1 | cut -d " " -f 1` echo "Vetting $1 commits of branch ${current_branch}." echo "Asked to test commits: $hashes" echo date >> $VETTED_COMMITS_FILE echo "Testing compilation of $1 commits start at tip of '$current_branch':" >> $VETTED_COMMITS_FILE for hash in $hashes do $CMD_GIT checkout --quiet $hash echo echo "At commit $hash, vetting script in progress" echo "---------------------------------------------" ./scripts/docker-helper.sh build_both_debug echo "$hash build result: $?" >> $VETTED_COMMITS_FILE done echo echo "Restoring git checkout to starting branch:" $CMD_GIT checkout $current_branch echo "$0: done." exit #?
^ To Research
[ ] Look up `git ls-files` and its options.
[ ] Review `xargs` called with the dash zero option.
Interesting header file from Zephyr RTOS 3.4.0:
`zephyr/include/zephyr/toolchain/xcc_missing_defs.h`