Difference between revisions of "Shell"

From Wiki at Neela Nurseries
Jump to navigation Jump to search
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:

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`