-1

I'm trying to interpret this tcsh code:

echo -n '$ '
set x = $<:q
echo $x:q
set x = ( `echo _$x:q | sed 's/\<-/\\-/g;' | tr '[?*' '\r\v\b'` )

but I have no idea what :q means. There's nothing earlier in the script declaring q. Isn't the < supposed to send a file as an input?

DanR
  • 7
  • 2
  • 1
    https://linux.die.net/man/1/tcsh etc; "When the ':q' modifier is applied to a substitution the variable will expand to multiple words with each word separated by a blank and quoted to prevent later command or filename substitution" and "$< Substitutes a line from the standard input, with no further interpretation thereafter. It can be used to read from the keyboard in a shell script. (+) While csh always quotes $<, as if it were equivalent to '$<:q', tcsh does not." – Dave Newton Jun 18 '21 at 15:17

1 Answers1

0

Variables in (t)csh can have :-modifiers; from the tcsh manpage:

   The word or words in a history reference can be edited, or
   ``modified'', by following it with one or more modifiers, each preceded
   by a `:':

       h       Remove a trailing pathname component, leaving the head.
       t       Remove all leading pathname components, leaving the tail.
       r       Remove a filename extension `.xxx', leaving the root name.
       e       Remove all but the extension.
       u       Uppercase the first lowercase letter.
       l       Lowercase the first uppercase letter.
       s/l/r/  Substitute l for r.  l is simply a string like r, not a
               regular expression as in the eponymous ed(1) command.  Any
               character may be used as the delimiter in place of `/'; a
               `\' can be used to quote the delimiter inside l and r.  The
               character `&' in the r is replaced by l; `\' also quotes
               `&'.  If l is empty (``''), the l from a previous
               substitution or the s from a previous search or event
               number in event specification is used.  The trailing
               delimiter may be omitted if it is immediately followed by a
               newline.
       &       Repeat the previous substitution.
       g       Apply the following modifier once to each word.
       a (+)   Apply the following modifier as many times as possible to a
               single word.  `a' and `g' can be used together to apply a
               modifier globally.  With the `s' modifier, only the
               patterns contained in the original word are substituted,
               not patterns that contain any substitution result.
       p       Print the new command line but do not execute it.
       q       Quote the substituted words, preventing further
               substitutions.
       Q       Same as q but in addition preserve empty variables as a
               string containing a NUL.  This is useful to preserve
               positional arguments for example:

                   > set args=('arg 1' '' 'arg 3')
                   > tcsh -f -c 'echo ${#argv}' $args:gQ
                   3
       x       Like q, but break into words at blanks, tabs and newlines.

So the :q modifier is used to "Quote the substituted words, preventing further substitutions".

This is mostly useful to prevent globbing (which is what is means with "substitutions", although there are some other types as well such as history substitution):

> set x = "star: *"

> echo $x:q
star: *

> echo "$x"
star: *

> echo $x
star: bin boot data dev etc home lib lib32 lib64 lost+found media mnt nix opt proc root run sbin sys tmp usr var

As you can see, you also could have used quotes; :q is more useful/readable in some contexts though.

Martin Tournoij
  • 26,737
  • 24
  • 105
  • 146