Re: ! history expansion occurs within arithmetic substitutions
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
Assignment to RO variable
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: Assignment to RO variable
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.
formatting man pages in email (was: Assignment to RO variable)
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: formatting man pages in email (was: Assignment to RO variable)
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. >