Re: formatting man pages in email (was: Assignment to RO variable)

2023-08-15 Thread Phi Debian
I find it usefull and keep it :-) Thanx tons.

  readonly [-aAf] [-p] [name[=word] ...]
>   The  given  names are marked readonly; the values of these
> names
>   may not be changed by subsequent assignment.  If the  -f
>  option
>   is  supplied,  the  functions  corresponding to the names
> are so
>   marked.  The -a option restricts the variables  to  indexed
>  ar‐
>   rays;  the  -A option restricts the variables to associative
> ar‐
>   rays.
>



On Wed, Aug 16, 2023 at 8:06 AM G. Branden Robinson <
g.branden.robin...@gmail.com> wrote:

> At 2023-08-15T23:24:31-0500, Dennis Williamson wrote:
> > From man bash:
> >
> > readonly [-aAf] [-p] [name[=word] ...]
> >   The given names are marked readonly; the values of these
> > names may not be changed by subsequent assignment.  If the -f option is
> > supplied, the functions
> >   corresponding to the names are so marked.  The -a option
>
> That man page quotation came out somewhat awkwardly.
>
> I often find myself quoting man pages in email, so I have a shell
> function for this scenario.  I call it "mailman", fully aware that
> that's also the name of mailing list manager.  (Even if I ran it, I
> wouldn't ever do so at an interactive shell prompt, because it's a
> daemon.)
>
> mailman () {
> local cmd= opts=
> case "$1" in
> (-*)
> opts="$opts $1"
> shift
> ;;
> esac
>
> set -- $(man -w "$@")
> cmd=$(zcat --force "$@" | \
> grog -Tutf8 -b -ww -P -cbou -rU0 -rLL=72n -rHY=0 -dAD=l)
> zcat --force "$@" | $cmd | less
> }
>
> This relies upon man-db man(1)'s `-w` option to locate the requested
> pages (and it does the right thing if you specify file names, not just
> page topics).
>
> It also uses grog(1), much improved in groff 1.23.0 (released 5 July),
> to figure out which preprocessor(s) and macro package the document
> needs.
>
> I'll walk through those groff options.
>
> * `-Tutf8` formats for a UTF-8 terminal.
> * `-P -cbou` passes options to grotty(1) to turn off all ISO
>   6429/ECMA-48 escape sequences, _and_ all overstriking sequences; their
>   formatting effects won't come through in plain text email anyway.
> * `-rHY=0` turns off hyphenation.
> * `-rLL=72n` sets the line length to 72 ens (character cells), which
>   helps prevent ugly line wrapping.
>
> Two options are new groff 1.23 features.
>
> * `-rU0` turns off hyperlink support, so that any URIs in the man page
>   will be formatted as text.  This is a new groff 1.23.0 feature.
> * `-dAD=l` turns off adjustment (the spreading of output lines).
>
> Two more options are ones I use, but maybe only maintainers of man pages
> want them.
>
> * `-b` produces backtraces for any formatter warnings or errors.
> * `-ww` turns on all formatter warnings.
>
> I hope people find this useful.
>


formatting man pages in email (was: Assignment to RO variable)

2023-08-15 Thread G. Branden Robinson
At 2023-08-15T23:24:31-0500, Dennis Williamson wrote:
> From man bash:
> 
> readonly [-aAf] [-p] [name[=word] ...]
>   The given names are marked readonly; the values of these
> names may not be changed by subsequent assignment.  If the -f option is
> supplied, the functions
>   corresponding to the names are so marked.  The -a option

That man page quotation came out somewhat awkwardly.

I often find myself quoting man pages in email, so I have a shell
function for this scenario.  I call it "mailman", fully aware that
that's also the name of mailing list manager.  (Even if I ran it, I
wouldn't ever do so at an interactive shell prompt, because it's a
daemon.)

mailman () {
local cmd= opts=
case "$1" in
(-*)
opts="$opts $1"
shift
;;
esac

set -- $(man -w "$@")
cmd=$(zcat --force "$@" | \
grog -Tutf8 -b -ww -P -cbou -rU0 -rLL=72n -rHY=0 -dAD=l)
zcat --force "$@" | $cmd | less
}

This relies upon man-db man(1)'s `-w` option to locate the requested
pages (and it does the right thing if you specify file names, not just
page topics).

It also uses grog(1), much improved in groff 1.23.0 (released 5 July),
to figure out which preprocessor(s) and macro package the document
needs.

I'll walk through those groff options.

* `-Tutf8` formats for a UTF-8 terminal.
* `-P -cbou` passes options to grotty(1) to turn off all ISO
  6429/ECMA-48 escape sequences, _and_ all overstriking sequences; their
  formatting effects won't come through in plain text email anyway.
* `-rHY=0` turns off hyphenation.
* `-rLL=72n` sets the line length to 72 ens (character cells), which
  helps prevent ugly line wrapping.

Two options are new groff 1.23 features.

* `-rU0` turns off hyperlink support, so that any URIs in the man page
  will be formatted as text.  This is a new groff 1.23.0 feature.
* `-dAD=l` turns off adjustment (the spreading of output lines).

Two more options are ones I use, but maybe only maintainers of man pages
want them.

* `-b` produces backtraces for any formatter warnings or errors.
* `-ww` turns on all formatter warnings.

I hope people find this useful.


signature.asc
Description: PGP signature


Re: Assignment to RO variable

2023-08-15 Thread Dennis Williamson
On Tue, Aug 15, 2023 at 8:57 PM Wiley Young  wrote:

> So this behavior of `bash`s seems like a bug to me. I stumbled across it by
> accident.
>
> From within a stack of x3 functions called from a case within a for loop,
> when trying to assign a value to a read-only variable, `printf` and `read`
> both fail with exit codes of 1, and the functions, `case` and `for`
> commands all complete.  When trying effectively the same thing with a
> simple assignment syntax, `x=z`, when the assignment fails, the functions
> return, `case` fails to complete and `for` returns an exit code of 1.
>
> It's probably a pretty rare use case, though. I tried this out on Android
> 12 on a Nokia in Termux and Fedora 38 on an HP in XFCE; that's all I've got
> for the time being. There isn't any pressing need to look into this one;
> I'm just curious. A reproducer's attached.
>
> Thanks & Happy summer,
> Wiley
>
> ###
> $ cat ro-var-in-fn.sh
> #!/bin/bash -x
>
> reset
> readonly x=y
> declare -p x SHELLOPTS BASHOPTS
> : "hyphen: $-"
>
> a(){ : go a; b $1; : end a;}
> b(){ : go b; c $1; : end b;}
> c(){
>   : go c
>   declare -p x
>
>   case "$1" in
> 1 )
>   false
>   : "exit, false: $?"
>   ;;
> 2 )
>   printf -v x '%s' $1
>   : "exit, printf: $?"
>   ;;
> 3 )
>   read -r x <<< $1
>   : "exit, read: $?"
>   ;;
> 4 )
>   x=$1
>   : "exit, var assignment: $?"
>   ;;
> 5 )
>   echo $1
>   ;;
>   esac
>   : "exit, case: $?"
>   : end c
> }
>
> declare -pf a b c
>
> for ii in {1..5}
> do
>   a $ii
>   : "exit, a $ii: $?"
> done
> : "exit, for loop: $?"
>
> ###
>

You have assigned the character "y" to the variable "x" which you've set to
read only using the readonly built. It is forever and always immutable (or
the shell it exists in exits).

>From man bash:

readonly [-aAf] [-p] [name[=word] ...]
  The given names are marked readonly; the values of these
names may not be changed by subsequent assignment.  If the -f option is
supplied, the functions
  corresponding to the names are so marked.  The -a option
restricts the variables to indexed arrays; the -A option restricts the
variables to associative arrays.  If
  both options are supplied, -A takes precedence.  If no name
arguments are given, or if the -p option is supplied, a list of all
readonly names is printed.  The
  other options may be used to restrict the output to a subset
of the set of readonly names.  The -p option causes output to be displayed
in a format that may be
  reused as input.  If a variable name is followed by =word,
the value of the variable is set to word.  The return status is 0 unless an
invalid option is
  encountered, one of the names is not a valid shell variable
name, or -f is supplied with a name that is not a function.

Your subsequent attempts to change the value of x will result in readonly
variable errors with a return status is 1 which will affect any logic
making use of it.

Don't use readonly unless you really mean it.

You should use more quotes around variables.

b "$1"
echo "$1"

Your use of colon as a comment character is confusing.

-- 
Visit serverfault.com to get your system administration questions answered.


Assignment to RO variable

2023-08-15 Thread Wiley Young
So this behavior of `bash`s seems like a bug to me. I stumbled across it by
accident.

>From within a stack of x3 functions called from a case within a for loop,
when trying to assign a value to a read-only variable, `printf` and `read`
both fail with exit codes of 1, and the functions, `case` and `for`
commands all complete.  When trying effectively the same thing with a
simple assignment syntax, `x=z`, when the assignment fails, the functions
return, `case` fails to complete and `for` returns an exit code of 1.

It's probably a pretty rare use case, though. I tried this out on Android
12 on a Nokia in Termux and Fedora 38 on an HP in XFCE; that's all I've got
for the time being. There isn't any pressing need to look into this one;
I'm just curious. A reproducer's attached.

Thanks & Happy summer,
Wiley

###
$ cat ro-var-in-fn.sh
#!/bin/bash -x

reset
readonly x=y
declare -p x SHELLOPTS BASHOPTS
: "hyphen: $-"

a(){ : go a; b $1; : end a;}
b(){ : go b; c $1; : end b;}
c(){
  : go c
  declare -p x

  case "$1" in
1 )
  false
  : "exit, false: $?"
  ;;
2 )
  printf -v x '%s' $1
  : "exit, printf: $?"
  ;;
3 )
  read -r x <<< $1
  : "exit, read: $?"
  ;;
4 )
  x=$1
  : "exit, var assignment: $?"
  ;;
5 )
  echo $1
  ;;
  esac
  : "exit, case: $?"
  : end c
}

declare -pf a b c

for ii in {1..5}
do
  a $ii
  : "exit, a $ii: $?"
done
: "exit, for loop: $?"

###


Re: ! history expansion occurs within arithmetic substitutions

2023-08-15 Thread Martin D Kealey
On Tue, 15 Aug 2023 at 01:41, Chet Ramey  wrote:

> On 8/11/23 4:19 PM, Martin D Kealey wrote:
> > I think it would be helpful to start this sentence with "The selected
> > line…", to differentiate from the line just entered containing a "!".
>
> It's both, actually. The line being expanded is broken into words to bound
> the history expansion, since a history expansion doesn't extend to multiple
> words, and the event is broken into words for the rest of the process.
>

While the delimiters for picking history expansions out of a line of input
include all (most of?) the things that cause words to be delimited at the
shell grammar level, it differs sufficiently that telling the user to
consider the shell grammar is misleading and quite unhelpful.

Examples:

1. history expansion a double quote (U+0022) read as input as a literal
character with no special meaning; it does not delimit the "word" as far as
history expansion goes (so you can search for it)
$ "echo" ls -ld
ls -ld
$ !"e
$ echo ls -ld
ls -ld
$ !":*
$ ls -ld
drwx-- 3 martin martin 280 2023-08-15 18:32:15.139812360 +1000 ./

2. The list of exempted characters only applies to whatever immediately
follows "!". After that the history expansion continues without regard for
word boundaries, simply stopping when the next character isn't valid given
the context.

In particular, the :s/// replacements treat everything except the delimiter
and \ as literals in the pattern:

$ echo cat > /dev/null
$ !!:s/>/<
[expands to] echo cat < /dev/null
cat
$ !!:s=ho ca=ho tom/ca=
[expands to] echo tom/cat < /dev/null
tom/cat
$ who="Chet's fan club"
$ echo 'Hello world, meet $who'
Hello world, meet $who
$ !!:gs/'/"/
[expands to] echo "Hello world, meet $who"
Hello world, meet Chet's fan club

So citing "word splitting" of the *input* line is badly misleading.

This is in sharp contrast to selecting words from the target line, where it
makes approximately mimics how words are split in the shell grammar:
$ echo "hi ho" "it's off to work we go"
hi ho it's off to work we go
$ !:0-1, !:1, !:2*
$ echo "hi ho", "hi ho", "it's off to work we go"
hi ho, hi ho, it's off to work we go

-Martin