[TUHS] A few comments on porting the Bourne shell

Alejandro Colomar alx.manpages at gmail.com
Thu Jan 5 11:51:28 AEST 2023


On 1/4/23 02:29, Adam Thornton wrote:
>> On Jan 3, 2023, at 10:26 AM, Dan Cross <crossd at gmail.com> wrote:
>>
>>
>> A few years ago, I was having lunch with some folks from the Go team
>> and one of them remarked, "you shouldn't write a shell script that's
>> longer than about 10 lines. Once you do, it's time to rewrite it in a
>> real programming language." I was a bit taken aback, but they had a
>> point. I'll note that Go standardized on using bash everywhere.


I have many counterexamples that take more than 10 lines.  I'll show a couple 
that are very useful to me:


#  man_section()  prints specific manual page sections (DESCRIPTION, SYNOPSIS,
# ...) of all manual pages in a directory (or in a single manual page file).
# Usage example:  .../man-pages$ man_section man2 SYNOPSIS 'SEE ALSO';

man_section()
{
	if [ $# -lt 2 ]; then
		>&2 echo "Usage: ${FUNCNAME[0]} <dir> <section>...";
		return $EX_USAGE;
	fi

	local page="$1";
	shift;
	local sect="$*";

	find "$page" -type f \
	|xargs wc -l \
	|grep -v -e '\b1 ' -e '\btotal\b' \
	|awk '{ print $2 }' \
	|sort \
	|while read -r manpage; do
		(sed -n '/^\.TH/,/^\.SH/{/^\.SH/!p}' <"$manpage";
		 for s in $sect; do
			<"$manpage" \
			sed -n \
				-e "/^\.SH $s/p" \
				-e "/^\.SH $s/,/^\.SH/{/^\.SH/!p}";
		 done;) \
		|man -P cat -l - 2>/dev/null;
	done;
}


I don't think it's unreadable by being too long, and in every other language it 
would take a lot more work to implement.  And here's another one, which I used a 
lot until I wrote grepc(1)[1]:


#  grep_syscall()  finds the prototype of a syscall in the kernel sources,
# printing the filename, line number, and the prototype.
# It should be run from the root of the linux kernel source tree.
# Usage example:  .../linux$ grep_syscall openat2;
#
# See also: grepc(1)

grep_syscall()
{
	if [ $# -ne 1 ]; then
		>&2 echo "Usage: ${FUNCNAME[0]} <syscall>";
		return $EX_USAGE;
	fi

	find ./* -type f \
	|grep '\.c$' \
	|xargs grep -l "$1" \
	|sort \
	|xargs pcregrep -Mn "(?s)^\w*SYSCALL_DEFINE.\($1\b.*?\)" \
	|sed -E 's/^[^:]+:[0-9]+:/&\n/';

	find ./* -type f \
	|grep '\.[ch]$' \
	|xargs grep -l "$1" \
	|sort \
	|xargs pcregrep -Mn "(?s)^asmlinkage\s+[\w\s]+\**sys_$1\s*\(.*?\)" \
	|sed -E 's/^[^:]+:[0-9]+:/&\n/';
}


Cheers,
Alex


[1]:  <http://www.alejandro-colomar.es/src/alx/alx/grepc.git/>


> 
> 
> My number is larger than 10, but it's smaller than 100.


More information about the TUHS mailing list