View Single Post
  #2   (View Single Post)  
Old 2nd February 2010
J65nko J65nko is offline
Administrator
 
Join Date: May 2008
Location: Budel - the Netherlands
Posts: 4,128
Default

1.2 Progressively cooking a nice 'al dente' 'sed' command file

The example from the previous section is not too difficult, an easily digested porridge. As an exercise to move beyond this stage and to become a 'real (wo)man', we will modify an '/etc/tttys' so we can connect to a computer with a serial connection. No more watery gui/desktop soup with hieroglyphs for us!

According to the OpenBSD FAQ we have to change

Code:
tty00   "/usr/libexec/getty std.9600"   unknown off
into

Code:
tty00   "/usr/libexec/getty std.9600"   vt220   on secure
To make it more challenging, we will save the original line. By prefixing the original line with a "#" comment, we can easily backout a modification.
  1. Select the line with 'tty00' and just print it.

    Code:
    $ sed -ne '/^tty00/p' /etc/ttys
    tty00   "/usr/libexec/getty std.9600"   vt220   off secure
    The -n option

    Code:
    -n     By default, each line of input is echoed to the standard output
           after all of the commands have been applied to it.  The -n option
           suppresses this behavior.
    By using this option we prevent the complete file from being echoed, both modified and unmodified lines. To force 'sed' to show us the changed line, we have to specify the p modifier in the /^tty00/ pattern.

    The same results, but now using a command file called 'sercon':

    Code:
    $ sed -nf sercon /etc/ttys
    tty00   "/usr/libexec/getty std.9600"   vt220   off secure
    The 'sercon' file:

    Code:
    /^tty00/ {
    p
    }
    For all lines containing the 'tty00' sequence at the beginning of the line, perform all commands between the starting "{" and closing "}".
  2. Saving a copy with a '#" in front.

    Code:
    /^tty00/ {
    h
    s/^/# /
    p
    g
    p
    }
    Explanation:

    Code:
    h	: save the current line (pattern space) into hold space
    	  do not delete pattern space
    
    s/^/# /	: replace the null string at begin of line ('^') with a
    	  '#' followed by a space
    p	: print the modified line from pattern space
    
    g	: get the line from hold space into pattern
    	  space, and overwrite whatever is in pattern space
     
    p	: print the line from pattern space
    The result:

    Code:
    $ sed -nf sercon /etc/ttys
    # tty00 "/usr/libexec/getty std.9600"   vt220   off secure
    tty00   "/usr/libexec/getty std.9600"   vt220   off secure
  3. Replace 'vt220' with 'xterm' and 'off' with 'on'

    Code:
    /^tty00/ {
    h
    s/^/# /
    p
    g
    s/vt220/xterm/
    s/off/on /
    p
    }
    The result:

    Code:
    $ sed -nf sercon /etc/ttys
    # tty00 "/usr/libexec/getty std.9600"   vt220   off secure
    tty00   "/usr/libexec/getty std.9600"   xterm   on  secure
  4. The command file, to insert "# --- original ---" and "# --- modified ---".

    Code:
    /^tty00/ {
    h
    i\
    # --- original ---
    s/^/# /
    p
    i\
    # --- modified ---
    g
    s/vt220/xterm/
    s/off/on /
    p
    }
    Code:
    $ sed -nf sercon /etc/ttys
    # --- original ---
    # tty00 "/usr/libexec/getty std.9600"   vt220   off secure
    # --- modified ---
    tty00   "/usr/libexec/getty std.9600"   xterm   on  secure
  5. For the final version we omit the -n option, but we see the tty00 line appear twice.

    Code:
    $ sed -f sercon /etc/ttys | less
    ttyCa   "/usr/libexec/getty Pc"         vt220   off secure
    ttyCb   "/usr/libexec/getty Pc"         vt220   off secure
    # --- original ---
    # tty00 "/usr/libexec/getty std.9600"   vt220   off secure
    # --- modified ---
    tty00   "/usr/libexec/getty std.9600"   xterm   on  secure
    tty00   "/usr/libexec/getty std.9600"   xterm   on  secure
    tty01   "/usr/libexec/getty std.9600"   vt220   off secure
    tty02   "/usr/libexec/getty std.9600"   unknown off
    But that is easily fixed by commenting out the last p command.

    Code:
    /^tty00/ {
    h
    i\
    # --- original ---
    s/^/# /
    p
    i\
    # --- modified ---
    g
    s/vt220/xterm/
    s/off/on /
    #p
    }
    The 'sed' output is now:

    Code:
    ttyCb   "/usr/libexec/getty Pc"         vt220   off secure
    # --- original ---
    # tty00 "/usr/libexec/getty std.9600"   vt220   off secure
    # --- modified ---
    tty00   "/usr/libexec/getty std.9600"   xterm   on  secure
    tty01   "/usr/libexec/getty std.9600"   vt220   off secure
  6. A last simple modification to enable both tty00 and tty01

    Code:
    /^tty00/,/^tty01/ {
    h
    i\
    # --- original ---
    s/^/# /
    p
    i\
    # --- modified ---
    g
    s/vt220/xterm/
    s/off/on /
    #p
    }
    The /^tty00/,/^tty01/ is what sed(1) calls an [2addr] An alternative would be to use /^tty0[01]/.

    Code:
    ttyCb   "/usr/libexec/getty Pc"         vt220   off secure
    # --- original ---
    # tty00 "/usr/libexec/getty std.9600"   vt220   off secure
    # --- modified ---
    tty00   "/usr/libexec/getty std.9600"   xterm   on  secure
    # --- original ---
    # tty01 "/usr/libexec/getty std.9600"   vt220   off secure
    # --- modified ---
    tty01   "/usr/libexec/getty std.9600"   xterm   on  secure
    tty02   "/usr/libexec/getty std.9600"   unknown off
__________________
You don't need to be a genius to debug a pf.conf firewall ruleset, you just need the guts to run tcpdump

Last edited by J65nko; 2nd February 2010 at 03:01 AM. Reason: Small typo
Reply With Quote