Jump to content

Tips&Tricks Bash tips and tricks


aru
 Share

Recommended Posts

 

arusabal

Moderator

Joined: 17 Apr 2002

Posts: 836

Location: Spain

 

Post Posted: Fri May 10, 2002 2:59 pm Post subject: Bash tips and tricks

_________________________________________________________________

 

 

This is going to be my tips and tricks tribute to the bash shell, which I believe is the soul of the GNU/Linux OS.

 

I'll post here any useful tips and tricks I'll find focusing to the bash shell. Please feel free to contribute to this section with your own set of tips and tricks.

 

At this time:

1. Bash history tips

2. The unknown $CDPATH variable

3. More on cd (typing errors)

4. Key bindings in bash shell

5. Bash? Please, help me!

6. The revenge of cd Twisted Evil (pushd/popd)

7. A couple of articles on tab completion including the very last features (thanks to frew and tom)

8. Here-Documents

9. First post of "SHELL PARAMETER EXPANSION" series

10. Trick: A fast way to comment-out blocks of script code

11. Using functions instead of aliases at .bashrc

12. A bizarre single-line-command to empty system logs

 

Last edited by arusabal on Sat Oct 12, 2002 4:31 pm, edited 20 times

in total

 

 

arusabal

Moderator

Joined: 17 Apr 2002

Posts: 836

Location: Spain

Post Posted: Wed May 15, 2002 10:04 pm Post subject:

_________________________________________________________________

 

 

Some bash-history tips

 

The usage of the bash-history feature could be as fun as helpful, also it can save a lot of time if you are one of those who use bash-terminals for everything (if you are not, what the hell are you doing here with Linux Mr. Green ...just kidding Wink )

 

I'm not going to talk in extent about the usage of bash-history, I only want to show you a couple of tips. If you want to learn more about it you can take a look to the chapter 7 of the Bash Reference Manual (such as ramfree "pointed" long time ago, should be under every linux user's pillow Wink )

 

Here are the tips:

~]$ !n --Will execute the line n of the history record.

~]$ !-n --Will execute the command n lines back.

~]$ !! --Will execute the last command. As !-1 or "up-arrow + return"

~]$ !string --Will execute the most recent command starting with the given string. In my experience string is just the first characters of the first word of the command, so don't use space characters.

~]$ !?string[?] --Will execute the most recent command containing the given string. The last "?" may be omitted if the string is followed by a new line. So if the string includes space characters or similar close it with "?". This can be used to avoid the error that appears with !string when used with long strings.

~]$ ^string1^string2 --String2 will substitute string1 on the last command. Cool, isn't it? This is equivalent to !!:s/string1/string2/ which is cooler Wink Any one feels a bit like in vi?

 

$HISTIGNORE or How-To improve the history usage:

 

You might want to set up the shell variable $HISTIGNORE to avoid having consecutive duplicate commands or unuseful commands appended to the history list. So you'll get rid of the never ending story of hitting the up arrow trough simple and repetitive commands.

 

Here is an example of usage:

 

export HISTIGNORE="&:l[sl]:[fb]g:exit"

 

Setting this way the $HISTIGNORE, the consecutive duplicated commands, the simple calls to ls, ll, fg and bg commands without arguments, and calls to the exit command will not be appended to the history list, so navigate though it will be much easier.

 

Bash-history has many other interesting things, take a look to the manual! ...and forgive me for the emoticons abuse Rolling Eyes Last edited by arusabal on Thu May 16, 2002 5:38 pm, edited 1 time in

total

 

 

arusabal

Moderator

Joined: 17 Apr 2002

Posts: 836

Location: Spain

Post Posted: Wed May 15, 2002 10:17 pm Post subject:

_________________________________________________________________

 

 

The un-known $CDPATH shell variable

 

This is a little known, *even to me* (as I discovered it tonight Wink ), shell variable. CDPATH does for the cd built-in command what PATH does for executables.

 

Please try it, you'll get surprised. For example:

 

Code:

~$ export CDPATH=~:/mnt:/usr/share/docs:/usr/src/RPMS:/usr/local/  

 

So once you set it, cd win_c would take you to /mnt/win_c/, or just typing cd HTML would take you to /usr/share/doc/HTML/.... Interesting, isn't it?

 

 

arusabal

Moderator

Joined: 17 Apr 2002

Posts: 836

Location: Spain

Post Posted: Wed May 15, 2002 10:48 pm Post subject:

_________________________________________________________________

 

 

More on cd stuff

 

cdspell

Have you ever got upset because you need to retype a cd to some directory command just for a little spelling error?

 

Well that can be avoid if you set on the cdspell option. Just open a bash terminal and type:

 

shopt -s cdspell

 

Now if you type:

cd /isr/src #<--- notice the 'i' Shocked

you'll get

[arusabal@paleo /usr/src]$

 

Linux is so cool!

 

Ofcourse you can set it to your bash_profile file, so every time you open a bash terminal you'll be helped in minor spelling errors Wink

 

 

arusabal

Moderator

Joined: 17 Apr 2002

Posts: 836

Location: Spain

Post Posted: Sat May 18, 2002 11:21 pm Post subject:

_________________________________________________________________

 

 

Key Bindings

 

Every one knows how to use the arrow keys to navigate trough history records, how to move forward and backwards along the command line, how to use command completion hitting the tab key, how to use the init and end keys, or other common combinations of keys, but during a bash terminal session you can use many other useful key bindings. Here I show you a list of the, to me, more useful ones:

 

Some common command line editing key-bindings:

 

Ctrl-l (as Ctrl-"L" not 1 or I)

Clear the screen (terminal) Same as `clear`, but can be used while writing a command without loosing the typing.

 

Ctrl-k

Kill the text from cursor position to the end of the line.

 

Ctrl-x backspace

Kill the text form cursor position to the beginning of the line.

 

Ctrl-a

Move to the start of the current line.

 

Ctrl-e

Move to the end of the current line.

 

Alt-b

Move backwards to the start of the current word or the previous. (text mode only, doesn't work in X)

 

Alt-f

Move to the end of the current word. (text mode only)

 

Ctrl-r

Reverse search history: search backwards starting at current line and moving up incrementally (see some posts above for more info).

 

Some other curious keybindings:

 

Alt-u

Uppercase the current word. (text mode only)

 

Alt-l ("L")

Down case the current word. (text mode only)

 

Alt-l ("L")

Capitalize the current word. (text mode only)

 

There are dozens of keybindings!!

 

The default line editing interface is emacs-like, if you are a vi fanatic you might want to use a vi-style line editing interface, so to switch betwen modes use this options:

set -o vi #vi-style

set -o emacs #emacs-style

 

Resources:

Here are some files you might check:

/etc/inputrc #System wide key bindings; you can re-read them any time by clicking ctrl-x Ctrl-r.

.inputrc #User's own settings

man 3 readline #Full information on Key Bindings and a list of them (many doesn't work on X)

 

 

arusabal

Moderator

Joined: 17 Apr 2002

Posts: 836

Location: Spain

Post Posted: Mon May 20, 2002 5:33 pm Post subject: Getting help

_________________________________________________________________

 

 

Bash? Please, help me!

 

You don't have any idea of what shopt does? Are you writing an script and it is reporting a syntax error? Did you ever forget how to use the if command? Use the help sytem!!!

 

There are two ways of getting instant help in bash, the first one is the ultra-known trick of looking into the man bash page Shocked , there you'll find all the info about bash shell/scripting you may need; But although using the man page is a great resource of help and info, this can be some times a bit nasty because that page is one of the looooooong ones Wink . The second way of getting instant help is the help built-in command, this one is a real fast way of getting instant help on all the bash built-in commands and its syntax. Here is an example of its usage:

 

help syntax: help [-s] COMMAND

 

Code:

[user@host user]$ help if



if: if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMANDS; ]... [ else COMMANDS; ] fi



The if COMMANDS are executed.  If the exit status is zero, then

the then COMMANDS are executed.  Otherwise, each of the elif COMMANDS

are executed in turn, and if the exit status is zero, the

corresponding then COMMANDS are executed and the if command

completes.  Otherwise, the else COMMANDS are executed, if present.

The exit status is the exit status of the last command executed, or

zero if no condition tested true.



[user@host user]$



 

 

Also, if you want a shorter output, maybe you only need to refresh your memory with the right syntax of a command, just use the option -s as follows:

 

Code:

[user@host user]$ help -s unset



unset: unset [-f] [-v] [name ...]



[user@host user]$



 

 

And finally, if you want a quick reference or a list of all the built-in commands, you'll just need to call help without arguments Wink

 

 

arusabal

Moderator

Joined: 17 Apr 2002

Posts: 836

Location: Spain

Post Posted: Mon May 20, 2002 6:50 pm Post subject:

_________________________________________________________________

 

 

The revenge of cd (the directory stack)

 

Lets suppose that you are working in the directory /usr/local/src/some_cool_program_but_with_a_long_name-0.0.123-beta/sou rce/ , you read the README file and then you notice that you have to edit some files in /etc , others in your /home directory, install some dependences form /mnt/cdrom/Mandrake/RPM/ and then go back to the program's source directory to compile it... Arrghh!!!! do I need to type again that long path????

 

No! you are lucky, there is something cool in the bash shell called the directory stack Cool

 

Lets rewind a bit. We were in /usr/local/src/some_cool_program_but_with_a_long_name-0.0.123-beta/source/ , remember?

 

Then to change to /etc instead of using cd /etc we'll do pushd /etc.

 

Doing such thing the directory where we were is saved on the top of the directory stack.

 

Once we finish all the work, installing, editing..., to go back to the original original directory, we'll only need to execute the command popd, and we'll be back again in /usr/local/src/some_cool_program_but_with_a_long_name-0.0.123-beta/source/ (Cool, isn't it?)

 

Epilogue:

 

The Directory Stack is a list of recently visited directories.

There are 4 bash built-in commands dedicated to it:

* dirs: Display the list of the currently remembered directories.

That is also available from the $DIRSTACK shell variable.

* pushd: Adds directories to the stack as it changes the current directory.

* popd: Removes specified directories from the stack and changes the current directory to the directory removed.

* dir: (not used in mandrake because of the default alias!!). Makes the current directory be the top of the stack, and then executes the equivalent of 'cd dir'.

 

Check the man page (or the help built-in) to navigate through the stack and to check which are the options that those commands accept.

 

 

frew

Senior user

Joined: 01 Jun 2002

Posts: 214

Location: Mississippi

Post Posted: Sat Jun 01, 2002 10:24 am Post subject: don't forget

the tab button

_________________________________________________________________

 

 

I know you didn't ask for this one, but its a lifesaver once you get used to it. Ever have to type in a program name thats obscure or a filename too? well this should help. say you want to open a file called some_cool_program_but_with_a_long_name-0.0.123-beta.txt and you want to edit it with your favorite editlor. well instead of copy/pasting or typing that whole thing you type

 

vi some<tab>

and it will complete it unless there is another file that begins with some.

 

 

arusabal

Moderator

Joined: 17 Apr 2002

Posts: 836

Location: Spain

Post Posted: Sun Jun 09, 2002 2:32 am Post subject: Re: don't

forget the tab button

_________________________________________________________________

 

 

Thanks frew for your tip!

You might want to check the following post with the newer and cooler bash tab completion feature Wink

 

 

arusabal

Moderator

Joined: 17 Apr 2002

Posts: 836

Location: Spain

Post Posted: Sun Jun 09, 2002 2:36 am Post subject:

_________________________________________________________________

 

 

bash Autocompletion on Steroids... Really

cool!!!

Stolen from tom's mandrakeforum article Wink

 

Posted by tom on Saturday, June 08 @ 05:00:00 PDT

bash is the standard shell on Linux. If you've ever used it (*grin*),

you will know about the auto-completion feature which expands file and

directory names in path names upon hitting the TAB key.

 

How about auto-completion for 'rpm', 'tar', 'zip', 'chown', 'mount',

'man', 'cvs', 'ssh', image, document and sound files? No problem ...

 

Get the 2.05a bash RPM from Cooker. Notice that this is a package in

development and its use is not supported by Mandrakesoft. Works fine

here, though. Get the 'bash-completion-[date]-[rev].noarch.rpm' from

Ian Mcdonald's website and install it.

 

OK, let the fun begin ...

1. Getting the right file at once:

 

Code:

   $ ls d*

  dictionary.lst  dwun-0.96e-1.i386.rpm  dwun- 0.96e.tar.gz

  $ tar tzf d[TAB]

     

auto-completes to the only file of those three which can be listed

by 'tar', dwun-0.96e.tar.gz. The same for rpm:

 

Code:

   rpm -qpl d[TAB]

     

auto-completes to the only RPM archive starting with 'd',

dwun-0.96e-1.i386.rpm.

This behaviour is preconfigured for a load of file types,

including PDF, image and sound files.

2. List options:

 

Code:

   cvs [TAB]

     

lists all available options to the 'cvs' command. Also works for

tar and rpm.

3. Complete arguments:

 

Code:

   man 5 re[TAB]

  regexp_table  relocated     resolv.conf   resolver

     

Especially useful with RPM:

 

Code:

   rpm -e ope[TAB]

  openssh          openssh-server   opera

  openssh-clients openssl

     

4. List available arguments:

 

Code:

   ssh [TAB]

     

lists all servers in your .known_hosts file as argument. Also

works with scp.

 

Code:

   mount [TAB]

     

lists all configured mount points.

 

This is but a very short list of the possibilities now open to you.

Have a glance at '/etc/bash_completion' to see what commands are

covered and try them out, or configure the file to match your personal

preferences (it's weekend anyway Wink ).

 

As of version 20020601, some things do not work (yet). The 'service'

and 'chkconfig' autocompletion requires an extra patch to bash-2.05a.

'urpmi' and friends are listed in '/etc/bash_completion', but don't

work for me.

 

Nevertheless, it's quite an amazing feature, and if you spend any

considerable lenght of time on the shell, you really, really *want*

this. Smile

 

<end of quote>

 

Nothing to add, seems really, really cool Cool

The only thing is that I hope that this feature won't eat my P200MMX resources Confused ... I'm going to try it!

 

 

arusabal

Moderator

Joined: 17 Apr 2002

Posts: 836

Location: Spain

Post Posted: Sat Jul 06, 2002 9:47 am Post subject:

_________________________________________________________________

 

 

Here Documents

 

Back with this anarchic tribute, today I'm going to introduce the redirections from "here documents"... (maybe some day I'll make a deeper post talking about redirections, but not today).

 

But, what are the "here documents"?

It's just a type of redirection that instructs the shell to read the input from the current source until a line that contains only a previously defined word (whatever word). Every line read up to that point is used as input.

 

This kind of redirection is very useful in bash scripts, but also very helpful in shell mode.

 

The format of the "here documents" is something like this:

 

Code:

   << word

  document line 1

  document line 2

  ...

  document line n

  word



 

 

or:

 

Code:

   <<- word

     document line 1

     document line 2

     ...

     document line n

  word



 

 

When used with '<<-' the "here document" is allowed to be indented; which will be much more pretty inside your scripts Wink

 

Now here comes the fun (a couple of usage examples):

 

*) As a replace of long "echo" strings inside a script . Some times I feel that is somewhat esthetically ugly to use many instances of "echo" or to use "echo -e" filling the text string with dozens of echo tags (n t ...).

This is much more pretty:

 

Code:

   ...your code...



  function helper() {

  cat <<- _END

  Usage:

     command -[uvhctdsat] file



     where:

        -u is required when...



        -v bla, bla, bla



        ...



        more blas



        ...



     if you need more help please contact to l_torvalds@linux.org



  GNU license...



  bla bla...



  _END #here ends the here document

  }



  ...your code...



 

 

Doing the same thing with "echo" would have been terribly ugly. With the "here document" your script will be much more elegant.

 

*)Just another example, this time focused to command line:

Usage of the here documents as a fast resource of creating multiple input lines when you are working in command line mode. The example shows how to quickly instruct wget to download multiple files from different places:

 

Code:

   [arusabal@mycomp ~]$ xargs wget -c << _Packages

  http://www.kernel.org/pub/linux/kernel/people/rml/preempt-kernel/v2.4/

  preempt-kernel-rml-2.4.18-5.patch

  http://www.zipworld.com.au/~akpm/linux/2.4.18-rc1-low-latency.patch.gz

  http://www.kernel.org/pub/linux/kernel/v2.4/linux-2.4.18.tar.gz

  _Packages



 

 

I'm leaving to your imagination other useful implementations of the "here document" concept

 

Note: there is no need at all to use "_" at the beginning of the delimiter word, but I love to do it Cool

 

 

arusabal

Moderator

Joined: 17 Apr 2002

Posts: 836

Location: Spain

Post Posted: Sat Aug 10, 2002 10:08 pm Post subject:

_________________________________________________________________

 

 

here is something very interesting for the dyslexics --like me-- that I've just discovered while surfing at http://bulmalug.net (spanish).

It's just another key binding to add to the list:

 

Ctrl-t

will transpose the two characters close to the cursor

 

For example, if you type a lot, it is quite common to change the order of the characters:

 

Code:

   $ sl [ctrl-t]



 

 

will be 'magically' converted to:

 

Code:

   $ ls



 

 

 

arusabal

Moderator

Joined: 17 Apr 2002

Posts: 836

Location: Spain

Post Posted: Mon Sep 09, 2002 1:30 pm Post subject: SHELL PARAMETER EXPANSION (1)

_________________________________________________________________

 

 

SHELL PARAMETER EXPANSION (1)

Squeezing bash variables at maximum!

 

This will be the first post of a series where I'll write about the awesome world of SHELL PARAMETER EXPANSION.

 

If you are usually using expressions such as:

[user@host ~]$ find . -regex ".* .*" -exec sh -c 'mv "$0" "${0/ /_}"' '{}' ;

 

Then you probably will find this series of postings unuseful or very basic leveled... I'm not a guru, you know that Rolling Eyes But anyhow, if that's your case, you are very welcome to participate by PM me any suggestions or examples you'll want me to include here Wink

 

If you are staring at the above expression and you have any/many difficulty to understand what the hell is that stuff, but you feel that behind it there is something plenty of fun, then this series of posts is written for you!!! Smile

 

I'll try my best to introduce you the 'Shell Parameter Expansion' bash features in an useful way: with plain explanations and, more important, with as many examples as I'm able to write/find!!!

 

I'll try to post each time a case of shell parameter expansion with useful examples. But as I'm a *lazy guy* I can't say which will be the rate of postings that I'll follow.

 

Notice that this will be a series of posts! so if you feel there is something missed, don't be impatient! everything will be covered at its time!

 

Again feel free to contribute to this series by PM-ing me any useful examples you want to share with all of us Smile

 

...and sorry for my english

 

 

arusabal

Moderator

Joined: 17 Apr 2002

Posts: 836

Location: Spain

Post Posted: Sun Sep 29, 2002 12:32 pm Post subject: Trick: A fast way to comment-out blocks of script code

_________________________________________________________________

 

 

Trick: A fast way to comment-out blocks of script code

Very useful for debugging purposes

("Anonymous Here Documents")

 

(I know, it is supposed that I'm writing a "Bash Parameter Expansion Series of Posts" for this thread... but I don't have enough time this days for anything Crying or Very sad )

 

Very often is useful to comment out blocks of code while you are writing a new script and you want to debug it. There are many ways to do this, the easiest way is to add a '#' character at the very beginning of each single line of the code block. That way means to spend many time editing line by line the code adding that '#' character, and after the test is finished, you'll need to remove, again, line by line the '#'.

 

Certainly there are several ways to improve the commenting with '#'. For example, if you write code with vim, the commands:

 

:<fist line number>,<last line number>s/^/# (To comment a range of lines)

:<fist line number>,<last line number>s/^#// (To uncomment them)

 

should do the job in a very fast and efficient manner.

 

But THAT's NOT Bash!

So as this is BASH tips&tricks, I propose you a cooler way to comment out blocks of code using just a couple of BASH features combined. Those features we'll need are: the 'Here Documents' and the bash-built-in ':'.

 

The Bash built-in command ':' does nothing apart of expanding arguments and performing redirections. Really, it does nothing, but is very useful in many situations, for example to protect some cases of Parameter Expansion (we will see some examples in future posts), or at loops (it is an equivalent of the command 'true', see it's man page), or here, to use combined with the "Here Documents" to comment-out blocks of code creating an "Anonymous Here Doc". Its return status is always zero (=true).

 

The Here Documents were explained in detail some posts above.

 

Back to the trick, let's suppose we have a script like this:

 

Code:

   #!/bin/bash

  var1=something

  var2=otherthing

  bla,bla,bla

  ...

  more code



  if [something]; then

  more things

  else

  some more

  fi



  other code here



  while condition; do

  code

  done



  and the end code

  exit 0

  #end of script



 

 

Now, imagine that something goes wrong with the script, and we think that is due to the "end code", so we want to test just the end code, but not the if block and the while loop, so we can comment those two blocks of code by an "anonymous here document":

: << _COMMENTED_BLOCK

code line1

code line2

...

_COMMENTED_BLOCK

 

so the at the above script this will be:

 

Code:

   #!/bin/bash

  var1=something

  var2=otherthing

  bla,bla,bla

  ...

  more code

  : << _COMMENT

  if [something]; then

  more things

  else

  some more

  fi

  _COMMENT



  other code here



  : << _COMMENT

  while condition; do

  code

  done

  _COMMENT



  and the end code

  exit 0

  #end of script



 

 

And when we execute the script the code inside the "anonymous here documents" wont be seen by the interpreter (that's not completely true, but explaining it will be beyond this post Wink ).

 

This is a superb way of debugging comfortably and fast long bash scripts.

 

You can also use the "anonymous here documents" to create self-documenting scripts, ie:

 

Code:

   : << _DOCUMENTATION

  The utility of this script is to be used as...

  ...

  then the parameters used should be...

  ...

  TODO:

  * Add code to do...

  * Check that thing...

  ...

  _DOCUMENTATION



 

 

so you'll see the documentation only when you open the script in an editor.

 

And that's it. I really hope that this could be of some utility for you!

 

 

arusabal

Moderator

Joined: 17 Apr 2002

Posts: 836

Location: Spain

Post Posted: Thu Oct 03, 2002 11:53 pm Post subject: Using

functions instead of aliases at .bashrc

_________________________________________________________________

 

 

Using functions instead of aliases at .bashrc

 

This post has been written after a hard complaint by ramfree ( Crying or Very sad ) at help with a bash alias, and thanks to 87GTR who started that thread and joehil for providing a couple of great examples. Very Happy

 

In .bashrc, among other thinks you can place aliases and functions. When you open a new bash session (independently(*) if it is a login session or not) the file .bashrc gets sourced(**). That means that all what you put in there is available for you during the session.

 

Bash aliases are a great way to write simple shortcuts for long commands:

alias whops="ps aux | grep -v USER | cut -d' ' -f1 | sort -u"

alias lp='lp -d $PRINTER' # Use an environment variable to define the default printer

alias netscape='/opt/netscape/netscape'

 

But despite of their inherent advantages, aliases lack of many features that one would desire in some cases, ie: they can't take arguments (I don't mean arguments for the program called by the alias, but arguments to the alias itself):

 

for example:

$ alias cd2iso='dd if=/dev/scd0 of=/tmp/$1'

will never work because $1 will be expanded to an environmental variable named 1, if any. So:

$ cd2iso image.iso

will result in

"dd if=/dev/scd0 of=/tmp/ image.iso"

 

So in these cases, the concept of function in bash becomes very useful. Shell functions are just a way to group commands using a single name for the group, here you can see that are somewhat related to aliases, but in a deeper sense functions are more related to scripts.

 

Functions can accept arguments, and like in scripts, those arguments became the positional parameters during its execution.

 

Also notice that variables defined inside a function are local variables, so they won't be seen by the parent shell after the function ends its job.

 

Functions are declared using this syntax:

 

Code:

   [ function ] name() { command-list; }

  or

  [ function ] name() {

          commands

          ...

          more commands

  }



 

 

So in the above example, if instead of using an alias you use a function, you'll achieve your goal:

function cd2iso() { dd if=/dev/scd0 of=/tmp/$1; } # (see the original thread for a slightly different implementation of this function.)

and thus:

$ cd2iso image.iso

will result in:

"dd if=/dev/scd0 of=/tmp/image.iso"

 

You can create your functions as complex as you wish (they can be used, in our context -sourced by .bashrc-, as highly available scripts).

 

joehill posted these excellent and useful examples of functions that can be declared within .bashrc:

 

Code:

   function mp3ren() { for i in *.mp3; do mv "$i" `echo $i | tr ' ' '_'`;done; }

  function mp3dec() { for i in *.mp3; do lame --decode $i `basename $i.mp3`.wav; done; }



 

 

And I propose, using "parameter expansion" (***), this correction to avoid the usage of external commands for a "higher" performance:

 

Code:

   function mp3ren() { for i in *.mp3; do mv "$i" "${i// /_}";done; }

  function mp3dec() { for i in *.mp3; do lame --decode $i ${i%".mp3"}.wav; done; }



 

 

To end, just this quote from the Bash Reference Manual: "For almost every purpose, aliases are superseded by shell functions".

 

I really hope that this post had been somehow useful for you! Very Happy

 

(*) To achieve this you'll need to be sure that .bash_profile/.profile sources .bashrc (but that's another history).

(**) Bash reads and executes commands from .bashrc but in the current shell not in a subshell. That fact means that its variables, its aliases and its functions are available during the session.

(***) I'll post the dedicated series soon (when I'll have more free time) Smile

 

 

 

guest72485

Frequent user

Joined: 05 Jun 2002

Posts: 56

 

Post Posted: Fri Oct 04, 2002 10:47 am Post subject:

_________________________________________________________________

 

 

hey thanks buddy, that was helpful

 

 

DOlson

Moderator

Joined: 16 Apr 2002

Posts: 2393

Location: Canada

Post Posted: Sat Oct 05, 2002 6:04 am Post subject:

_________________________________________________________________

 

 

WOOHOO!!!!!!!!!!!!!

 

function mkcd() { mkdir $1; cd $1; }

 

I've always wanted to do that!!!!!!!!! Alias sucks!

 

 

joehill

Senior user

Joined: 09 May 2002

Posts: 217

Location: Toronto, Canada

Post Posted: Sat Oct 05, 2002 6:44 am Post subject:

_________________________________________________________________

 

 

sweeeeeeeeeeeet

 

good thinkin monsieur!

 

(i know how much you love that)

 

 

DOlson

Moderator

Joined: 16 Apr 2002

Posts: 2393

Location: Canada

Post Posted: Sat Oct 05, 2002 7:16 am Post subject:

_________________________________________________________________

 

 

Haha. I wanted to do that forever. I tried a bash script and everything. Nothing worked properly.

 

 

arusabal

Moderator

Joined: 17 Apr 2002

Posts: 836

Location: Spain

Post Posted: Sat Oct 05, 2002 8:56 am Post subject:

_________________________________________________________________

 

 

DOlson wrote:

WOOHOO!!!!!!!!!!!!!

 

function mkcd() { mkdir $1; cd $1; }

 

Cool! But this version will be better, since you'll prevent errors caused by the missing of an argument (destination dir):

 

function mkcd() { mkdir ${1?"error; usage: mkdir <new directory>"} && cd $1; }

 

Thanks guys for your posts, but damn! I'm very frustated right now! what about the other 12 articles!!!!!!! you are only interested in the last one. That gives the reason to ramfree Crying or Very sad Laughing

 

 

ramfree17

Moderator

Joined: 18 Apr 2002

Posts: 1262

Location: Philippines

Post Posted: Sat Oct 05, 2002 4:21 pm Post subject:

_________________________________________________________________

 

 

because thats the only one we could use on a day to day basis. Very Happy

 

but dont stop aru, who knows, i might have to use the others someday. but first i have to remember them and that means reading them once again.... hehehehehe..

 

ciao!

 

 

cannonfodder

Moderator

Joined: 16 Apr 2002

Posts: 1056

Location: Rochester, NY, USA

Post Posted: Sat Oct 05, 2002 4:54 pm Post subject:

_________________________________________________________________

 

 

I like this set of alias, its real fun!

 

alias bendover='clear'

alias aim='ll'

alias kickme='bendover;aim;kickme'

 

Rolling Eyes

 

 

DOlson

Moderator

Joined: 16 Apr 2002

Posts: 2393

Location: Canada

Post Posted: Sat Oct 05, 2002 8:59 pm Post subject:

_________________________________________________________________

 

 

arusabal wrote:

 

DOlson wrote:

WOOHOO!!!!!!!!!!!!!

 

function mkcd() { mkdir $1; cd $1; }

 

 

Cool! But this version will be better, since you'll prevent errors

caused by the missing of an argument (destination dir):

 

function mkcd() { mkdir ${1?"error; usage: mkdir <new directory>"} && cd $1; }

 

Thanks guys for your posts, but damn! I'm very frustated right now! what about the other 12 articles!!!!!!! you are only interested in the last one. That gives the reason to ramfree Crying or Very sad Laughing

 

I don't make misteaks.

 

 

arusabal

Moderator

Joined: 17 Apr 2002

Posts: 836

Location: Spain

Post Posted: Sat Oct 12, 2002 4:17 pm Post subject:

_________________________________________________________________

 

 

A bizarre single-line-command to empty system logs

Another day to day "usable" trick Rolling Eyes

 

Today I'm very bored, so after a PM from "ian malcom" about logrotate, my ill mind decided to write a single line command to do the following:

1. Empty all the log files from /var/log, saving just the last 50 lines of each one.

2. Delete the useless (at least for me) *.gz log files.

3. Do it recursively in all the /var/log tree.

4. Must be a single line command.

5. It has to be fun, because I'm bored.

 

Previous status:

 

Code:

   root@host]# du -sh /var/log

  193M    /var/log



 

 

There were 21 directories and 145 files (where 50 were .gz files)

 

The single-line command:

 

Code:

root@host]# find /var/log -type f -exec sh -c '[[ "${1##*.}" == "gz"]] && rm $1 || (tail -50 $1 > ${1}.tmp && cat ${1}.tmp > $1 && rm ${1}.tmp)' '{}' '{}';

 

The result:

 

Code:

   root@host]# du -sh /var/log

  665k    /var/log



 

 

and the tree command shows:

21 directories and 95 files.

 

Despite the command syntax is quite bizarre, you'll must admit that it is coooool!!!! Cool

 

The explanation:

First the most difficult here, the trick with find: Instead of executing the commands directly to the "-exec" find flag, which is almost impossible, I open a sh session with a -c flag (just reads and executes commands (and finally exits) from the string '<insert here the code>' , and any remaining argument is seen as positional arguments, that's why there are those '{}' '{}' <-- really only one is needed, but then the argument will be $0 which might confuse with normal positional arguments in scripts). For those who don't know it, '{}' is the way find shows its search results to the -exec part. To end with find, "/var/log" is the searching path and "-type f " means only files.

 

Now the "sh" part (remember that the searching results generated by find are passed one by one as $1 to sh -c):

 

Code:

[[ "${1##*.}" == "gz" ]] && rm $1 || (tail -50 $1 > ${1}.tmp && cat ${1}.tmp > $1 && rm ${1}.tmp)  

 

The first part, is just a conditional construct:

 

Code:

 [[ "${1##*.}" == "gz" ]]

 

That code will return true if the string that results in the "parameter expansion" stuff is equal to "gz" (Those gzip compressed log files). The expression ${1##*.} means that if the pattern "*."

matches the beginning of our parameter "$1" (ie: "/var/log/cron/errors.3.gz"), then the longest "##" matching pattern is deleted (all the stuff including the last "."), so then returning just the string "gz".

 

if the conditional construct returns true, then the block of code after the "&&" (and) is executed:

 

Code:

rm $1  

 

That means deletion of *.gz

 

But if the conditional construct returns false, meaning that the file is not a gzip compressed log file, then the block of code after the "||" (or) is executed:

 

Code:

(tail -50 $1 > ${1}.tmp && cat ${1}.tmp > $1 && rm ${1}.tmp)  

 

I've put the code between ( ) to avoid problems of interpretation. That block of code means:

tail -50 $1 > ${1}.tmp # Save the last 50 lines of $1 to a temporary file named $1.tmp; ie: tail -50 /var/log/messages > /var/log/messages.tmp If that is achieved without error (&&), then:

cat ${1}.tmp > $1 && rm ${1}.tmp # overwrite the original file with the contents of the temporary one and finally delete the temporary file.

 

Again, and again: UNIX (GNU/Linux) is so cool!!!

 

 

joehill

Senior user

Joined: 09 May 2002

Posts: 217

Location: Toronto, Canada

Post Posted: Wed Oct 16, 2002 7:35 pm Post subject:

_________________________________________________________________

 

 

you are a freaking genius. really.

 

 

arusabal

Moderator

Joined: 17 Apr 2002

Posts: 836

Location: Spain

Post Posted: Thu Oct 17, 2002 9:16 am Post subject:

_________________________________________________________________

 

 

Embarassed well, thanks, I'm just a bash junkie ( need bash to live!!! )

 

 

joehill

Senior user

Joined: 09 May 2002

Posts: 217

Location: Toronto, Canada

Post Posted: Thu Oct 17, 2002 11:35 am Post subject:

_________________________________________________________________

 

 

genius, junkie, same thing...

 

 

rolf

Moderator

Joined: 16 Apr 2002

Posts: 968

Location: Oakland, CA USA

Post Posted: Tue Nov 12, 2002 1:16 am Post subject: a tribute to

this thread

_________________________________________________________________

 

 

Thanks, all, especially arusabal. I had this thread in the back of my mind until today, when, after substantial perusal of bash resources, the answer was revealed in the use of function.

 

What I wanted to do was create an alias for a command line using this neato script for printing addresses, including my return address, on envelopes, giving only a text file containing the 'To' address as argument to:

 

/home/rolf/envelope/envelope <file> | lpr

 

which prints out the envelope as configured in an .enveloperc file, including a bar code, which is handy for mailing invoices for my small handyman business.

 

As we all know, I was not able to use a variable for the text file argument in an alias, despite lengthy trial and error. What is working is to put

 

function e() { /home/rolf/envelope/envelope $1|lpr; }

 

at the bottom of ~/.bashrc and I only have to do, in the directory containing my address files:

 

e <file>

 

to have the envelope printed out. Thanks for this helpful thread Smile

 

 

arusabal

Moderator

Joined: 17 Apr 2002

Posts: 836

Location: Spain

Post Posted: Tue Nov 12, 2002 5:22 pm Post subject:

_________________________________________________________________

 

 

You are wellcome rolf Smile

 

 

 

Editor's note: This thread was originally posted at the old MUB (Mandrake User Board at club-nihil). This post is the result of a 99% automatic backup, so due to its nature some text may be lost (improbable but possible).

Link to comment
Share on other sites

  • 1 year later...
  • 8 months later...

root@laptop.home /home/omar 0005 02-Dec-04
> find /var/log -type f -exec "sh -c '[[ "${1##*.}" == "gz"]] && rm $1 || (tail -50 $1 > ${1}.tmp && cat ${1}.tmp > $1 && rm ${1}.tmp)' '{}' '{}';"
find: missing argument to `-exec'

 

What's wrong?

Link to comment
Share on other sites

theYinYeti is right.

The command as it was originally posted was (from my own tricks repository folder):

find /var/log -type f -exec sh -c '[[ "${1##*.}" == "gz" ]] && rm $1 || (tail -50 $1 > ${1}.tmp && cat ${1}.tmp > $1 && rm ${1}.tmp)' '{}' '{}' \;

 

Editor's note: This thread was originally posted at the old MUB (Mandrake User Board at club-nihil). This post is the result of a 99% automatic backup, so due to its nature some text may be lost (improbable but possible).

well it was not so improbable, was it? :?

 

It looks like some special characters (such as \) in particular contex were lost

Edited by aru
Link to comment
Share on other sites

May I add this tip of mine:

#!/bin/bash
# $1 is the string to find
# $2 is the string that will replace it

eval sed '"s/'"$(sed -e 's/\([]\/*^$[]\)/\\\\\1/g' -e 's/"/\\"/g' <<<"$1")"'/'"$(sed -e 's/\([\/]\)/\\\\\1/g' -e 's/"/\\"/g' <<<"$2")"'/g"'

Usage example:

$ echo 'test "\(hello\)" [you] ^' | replace.sh '"\(hello\)"' "there's only \1 like"

test there's only \1 like [you] ^

If you followed well, you understand that this script is a replacement script for strings, not regexp (as sed would normally do).

 

Yves.

Edited by theYinYeti
Link to comment
Share on other sites

I just noticed something in the original (great) articles is out of date; it no longer needs to reference Cooker bash and external bash-completion, as both a bash that supports extended completion and a working bash-completion package are in stable Mandrake now. You can just 'urpmi bash-completion'. Could it perhaps be edited?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

×
×
  • Create New...