Tag: bash
Create links with absolute paths in Linux
by Mostafa on Jan.16, 2010, under How To ..., Linux, Software
The default behaviour of the linking command (ln) is a little strange under certain circumstances. Since it creates the links using the literal value of the target, symbolic links created using relative path structures can often fail. Consider the following:
$ ln -s targetfile ../src/targetfile_link
Without a doubt, ‘targetfile_link’ will be a broken symlink since it links to a target that it assumes is in the same directory:
$ cd ../src && ls -l targetfile_link lrwxrwxrwx 1 mafgani mafgani 5 2010-01-16 18:19 targetfile_link -> targetfile
This is quite unfortunate since it clearly clashes with the way that the linking mechanism should work intuitively.
The solution is to force ln into automatically appending the absolute path to the target files. This can be achieved by using a simple shell script that acts as a wrapper for the real linking command:
#!/bin/sh # Step through the supplied arguments and append the absolute # path to targets that exist for ARG in $@ do if [ -e $ARG ]; then LNARGS="${LNARGS} ${PWD}/${ARG}"; else LNARGS="${LNARGS} ${ARG}"; fi done # Execute the actual link command with the modified args exec /bin/ln ${LNARGS};
There are two known caveats:
- The link is ‘sub-optimal’ if created from within the destination directory (the absolute path contains ‘../’s). It will still work however.
- The links will always be absolute. If that is undesirable, save the script as ‘absln’ or something other than ‘ln’.
Using ‘absln’ instead of ‘ln’ in the previously described scenario now produces a working symlink:
$ absln -s targetfile ../src/targetfile_link $ cd ../src/ && ls -l targetfile_link lrwxrwxrwx 1 mafgani mafgani 16 2010-01-16 19:13 targetfile_link -> /tmp/files/targetfile
Bash process substitution
by Mostafa on Oct.03, 2008, under Linux, Software
From the Advanced Bash-Scripting Guide:
“Piping the stdout of a command into the stdin of another is a powerful technique. But, what if you need to pipe the stdout of multiple commands? This is where process substitution comes in.
Process substitution feeds the output of a process (or processes) into the stdin of another process.”
The syntax is:
>(cmd_list) <(cmd_list)
Example: comparing the head of two files using diff
$ diff -u <(head -n3 /var/log/dmesg) <(head -n3 /tmp/dmesg) --- /proc/self/fd/63 2009-05-26 19:52:45.144544140 +0100 +++ /proc/self/fd/62 2009-05-26 19:52:45.149544007 +0100 @@ -1,3 +1,3 @@ -Initializing cgroup subsys cpuset -Initializing cgroup subsys cpu -Linux version 2.6.27.21-170.2.56.fc10.i686 (mockbuild@xenbuilder2.fedora.redhat.com) (gcc version 4.3.2 20081105 (Red Hat 4.3.2-7) (GCC) ) #1 SMP Mon Mar 23 23:37:54 EDT 2009 +Linux version 2.6.22.9-61.fc6 (brewbuilder@hs20-bc2-4.build.redhat.com) (gcc version 4.1.2 20070626 (Red Hat 4.1.2-13)) #1 SMP Thu Sep 27 18:48:03 EDT 2007 +BIOS-provided physical RAM map: + BIOS-e820: 0000000000000000 - 000000000009f000 (usable)
The diff header clearly shows that file descriptors are used as the underlying mechanism.
BASH as a simple calculator
by Mostafa on Sep.25, 2006, under How To ..., Linux, Software
As long as you are satisfied with integer results:
[darkknight@darkworld ~]$ echo $[32 * 98] 3136 [darkknight@darkworld ~]$ echo $[332 / 98] 3 [darkknight@darkworld ~]$ echo $[29 + 56] 85 [darkknight@darkworld ~]$ echo $[29 - 156] -127
For full precision, one can use bc:
$ bc -l bc 1.06 Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc. This is free software with ABSOLUTELY NO WARRANTY. For details type `warranty'. 332/98 3.38775510204081632653
Creating directory hierarchies in bash
by Mostafa on Jul.16, 2006, under How To ..., Linux, Software
The BASH ‘brace expansion‘ feature can be used to create whole directory trees using a single command. From the man page for BASH:
Brace Expansion Brace expansion is a mechanism by which arbitrary strings may be gener? ated. This mechanism is similar to pathname expansion, but the file? names generated need not exist. Patterns to be brace expanded take the form of an optional preamble, followed by either a series of comma-sep? arated strings or a sequence expression between a pair of braces, fol? lowed by an optional postscript. The preamble is prefixed to each string contained within the braces, and the postscript is then appended to each resulting string, expanding left to right. Brace expansions may be nested. The results of each expanded string are not sorted; left to right order is preserved. For example, a{d,c,b}e expands into `ade ace abe'. A sequence expression takes the form {x..y}, where x and y are either integers or single characters. When integers are supplied, the expres? sion expands to each number between x and y, inclusive. When charac? ters are supplied, the expression expands to each character lexico? graphically between x and y, inclusive. Note that both x and y must be of the same type. Brace expansion is performed before any other expansions, and any char? acters special to other expansions are preserved in the result. It is strictly textual. Bash does not apply any syntactic interpretation to the context of the expansion or the text between the braces. A correctly-formed brace expansion must contain unquoted opening and closing braces, and at least one unquoted comma or a valid sequence expression. Any incorrectly formed brace expansion is left unchanged. A { or , may be quoted with a backslash to prevent its being considered part of a brace expression. To avoid conflicts with parameter expan? sion, the string ${ is not considered eligible for brace expansion. This construct is typically used as shorthand when the common prefix of the strings to be generated is longer than in the above example: mkdir /usr/local/src/bash/{old,new,dist,bugs} or chown root /usr/{ucb/{ex,edit},lib/{ex?.?*,how_ex}} Brace expansion introduces a slight incompatibility with historical versions of sh. sh does not treat opening or closing braces specially when they appear as part of a word, and preserves them in the output. Bash removes braces from words as a consequence of brace expansion. For example, a word entered to sh as file{1,2} appears identically in the output. The same word is output as file1 file2 after expansion by bash. If strict compatibility with sh is desired, start bash with the +B option or disable brace expansion with the +B option to the set com? mand (see SHELL BUILTIN COMMANDS below).
So, for example:
$ mkdir -p root/{1/{1.1,1.2,1.3},2,3/{3.1,3.2/{3.2.1,3.2.2}}} $ tree . `-- root |-- 1 | |-- 1.1 | |-- 1.2 | `-- 1.3 |-- 2 `-- 3 |-- 3.1 `-- 3.2 |-- 3.2.1 `-- 3.2.2 11 directories, 0 files
The ‘-p’ option to mkdir makes it create the parent directories if they do not exist.
BASH Commands
by Mostafa on Feb.14, 2006, under Linux, Software
Here’s a nice list:
Bash scripting guides
by Mostafa on Dec.30, 2005, under Linux, Software
Here’s a modest list:
http://www.tldp.org/LDP/Bash-Beginners-Guide/html/
http://www.opengroup.org/onlinepubs/009695399/toc.htm
http://cfaj.freeshell.org/shell/
http://www.shelldorado.com/
http://home.comcast.net/~j.p.h/cus-faq.html
http://sed.sourceforge.net/sed1line.txt
http://www.student.northpark.edu/pemente/sed/sedfaq.html
http://www.faqs.org/faqs/unix-faq/faq/part1/
http://www.shelldorado.com/goodcoding/cmdargs.html
http://www.macobserver.com/tips/macosxcl101/
http://www.wagoneers.com/UNIX/FIND/find-usage.html
http://cnswww.cns.cwru.edu/~chet/bash/bashref.html
http://www.tldp.org/LDP/abs/html/
Got the links from a post by Charles Howse on the 30th of December 2005 to the thread Why questions don’t get answered, or “No, I’ve already RTFM, tell me the answer!” on fedora-list.
Command line search utility
by Mostafa on Dec.27, 2005, under How To ..., Linux, Software
While studying for one of the finals this year, I felt the need for a CLI search utility that would search on Google, Wikipedia, Google Images, etc. I didn’t know of any tools that would already do this so I decided to write my own little bash script:
#!/bin/bash #Needs the htmlview package opt="$1" str="$2" #Create the search string until [ -z "$3" ] do str="$str+$3" shift done case "$opt" in "google" ) htmlview http://www.google.com/search?hl=en\&q="$str"&btnG=Google+Search & ;; "image" ) htmlview http://images.google.com/images?q="$str"\&safe=off & ;; "wpedia" ) htmlview http://en.wikipedia.org/wiki/Special:Search?search="$str" & ;; "scholar" ) htmlview http://scholar.google.com/scholar?q="$str"\&ie=UTF-8\&oe=UTF-8\&hl=en\&btnG=Search & ;; "ieee" ) htmlview http://ieeexplore.ieee.org/search/searchresult.jsp?queryText=\%28\%28"$str"\%29\%3Cin\%3Emetadata\%29 & ;; * ) echo "Usage: search engine searchterm [searchterms]" echo echo "Engines: google Basic Google websearch" echo " image Unfiltered Google image search" echo " wpedia Wikipedia (English)" echo " scholar Google Scholar" echo " ieee IEEE Xplore (needs subscription)" echo echo "Example: search image batman" ;; esac echo exit 0
It makes use of the htmlview package to discover the default browser and display the results. The use of the script is quite straightforward:
[darkknight@darkworld bin]$ search image batman begins
As is, it considers all search terms. Fancy things like Boolean expressions are not supported (yet :)). A copy of the script can be found here.