Thursday, March 17, 2011

File descriptors for read loops...

while read with a command that eats input (ssh, another read etc)

for file:


$ cat $tempfile
a b
c d
e f
g h


In ksh:


#!/bin/ksh

exec 4<$tempfile
while read -u4 first second
do
  echo first=$first
  echo second=$second
  printf "number?: "
  read NUM
  echo "name=$NUM"
  ssh localhost uname 2>/dev/null
done


in bash:


#!/bin/bash

exec 4<$tempfile
while read <&4 first second
do
  echo first=$first
  echo second=$second
  printf "number?: "
  read NUM
  echo "name=$NUM"
  ssh localhost uname 2>/dev/null
done

exec 4<&-


ksh: http://unix.derkeiler.com/Newsgroups/comp.unix.shell/2003-05/0889.html

bash: http://forums.devshed.com/unix-help-35/bash-scripting-using-file-descriptors-154812.html

Wednesday, March 16, 2011

Repeat after me, awk is not Perl...

What does a semicolon mean to awk?

This works:

$ /usr/bin/ps -ef | awk '/ root\ /{p++};END{print p}'


but this doesn't:

$ /usr/bin/ps -ef | awk 'BEGIN{p=0};/ root\ /{p++}END{print p}'
awk: syntax error near line 1
awk: bailing out near line 1


and this does:

$ /usr/bin/ps -ef | awk 'BEGIN{p=0}/ root\ /{p++}END{print p}'
0


and just to prove it's REALLY niggly, it's fussy about the order you give it things too:


$ /usr/bin/ps -ef | awk '/ root\ /{p++}BEGIN{p=0}END{print p}'
awk: syntax error near line 1
awk: bailing out near line 1


while this works fine:


$ /usr/bin/ps -ef | awk 'BEGIN{p=0}END{print p}'
0

Wednesday, March 02, 2011

Backticks can be dangerous!

For years I've preferred to use

$(command)

rather than

`command`

while shell scripting.

For me it was mostly a matter of style, but I pretty much thought that the two were equivalents.
I felt it was a bit easier to see $(...) than `...` and sometimes I need to nest commands with:

$(command $(othercommand))

which would be impossible with backticks.

THEY ARE NOT THE SAME!


#!/bin/ksh
#
#
#

for STRING in 'sample.txt' 'File: C:\\path\\to\\file.txt|Something else'
do

printf "result: "
echo "$STRING" | sed 's/^[^|]*\\\([^\\]*\)|.*$/\1/g'
echo 1
VAR_1=$(echo "$STRING" | sed 's/^[^|]*\\\([^\\]*\)|.*$/\1/g')
echo 2
VAR_2=`echo "$STRING" | sed 's/^[^|]*\\\([^\\]*\)|.*$/\1/g'`
echo 3
VAR_3=`echo "$STRING" | sed "s/^[^|]*\\\([^\\]*\)|.*$/\1/g"`
echo 4
VAR_4=`echo "$STRING" | sed 's/^[^|]*\\\\\([^\\]*\\)|.*$/\1/g'`

cat <<EOT
VAR_1: '$VAR_1'
VAR_2: '$VAR_2'
VAR_3: '$VAR_3'
VAR_4: '$VAR_4'
EOT

done


Don't blame ksh, it does the same in bash and Bourne shell.
(although $( ) syntax is not valid in Bourne shell)

Solaris:

$ uname -a
SunOS umurxd04 5.10 Generic_137138-09 i86pc i386 i86pc
$ ./try.sh
result: sample.txt
1
2
sed: command garbled: s/^[^|]*\\([^\]*\)|.*$/\1/g
3
4
VAR_1: 'sample.txt'
VAR_2: ''
VAR_3: 'sample.txt'
VAR_4: 'sample.txt'
result: file.txt
1
2
sed: command garbled: s/^[^|]*\\([^\]*\)|.*$/\1/g
3
4
VAR_1: 'file.txt'
VAR_2: ''
VAR_3: ''
VAR_4: 'file.txt'


Linux:

$ ./try.sh
sample.txt
1
2
sed: -e expression #1, char 27: Unmatched ) or \)
3
4
VAR_1: 'sample.txt'
VAR_2: ''
VAR_3: 'sample.txt'
VAR_4: 'sample.txt'
file.txt
1
2
sed: -e expression #1, char 27: Unmatched ) or \)
3
4
VAR_1: 'file.txt'
VAR_2: ''
VAR_3: ''
VAR_4: 'file.txt'


More testing:


ksh $ echo `echo '\\'`
\
ksh $ echo `echo "\\"`
"
ksh $ echo `echo "\\\"`
\



ksh $ echo $(echo '\\')
\
ksh $ echo $(echo "\\")
\
ksh $ echo $(echo "\\\")
>
> ^C



bash $ echo `echo '\\'`
\
bash $ echo `echo "\\"`
bash: command substitution: line 1: unexpected EOF while looking for matching `"'
bash: command substitution: line 2: syntax error: unexpected end of file

bash $ echo `echo "\\\"`
\



bash $ echo $(echo '\\')
\\
bash $ echo $(echo "\\")
\
bash $ echo $(echo "\\\")
>
>

Thursday, January 27, 2011

git bits...




http://www.draconianoverlord.com/2010/03/04/git-config.html
http://www.sourcemage.org/Git_Guide
http://cheat.errtheblog.com/s/git
http://www.gitready.com/intermediate/2009/02/06/helpful-command-aliases.html

Toggle Character Codes

In Windows, when you enter text you can press Alt-X after it to show the hex for that character. (inversely you can type a number and do Alt-X to make the character, or hold Alt & type the number on the numeric keypad to get the character)

Wednesday, January 12, 2011

vim one liner to convert backslashes in clipboard to percents

Windows clipboard modifier in vim...


I was exporting a whole lot of registry entries in Windows.
I would do F3 to find the next match, right click & click "Export",
then select the whole key name, the press ^C to copy
Then go to vim and press v to run the mapped macro below.
Then go to the filename box and press ^V to paste & click save.


:map v dd"+gP^Q:%s/\\/%/g^Q^MV"+y


Which looks like:


:map v dd"+gP^[:%s/\\/%/g^MV"+y


The macro takes the one line in the clipboard like:

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.htm\OpenWithProgids.reg

and converts it to:

HKEY_CURRENT_USER%Software%Microsoft%Windows%CurrentVersion%Explorer%FileExts%.htm%OpenWithProgids.reg

and copies it back to the clipboard.

Apache Directory Index

http://httpd.apache.org/docs/current/mod/mod_autoindex.html



IndexOptions NameWidth=* FancyIndexing FoldersFirst HTMLTable SuppressHTMLPreamble VersionSort IgnoreCase

Wednesday, January 05, 2011