MandrivaUsers.org : Tips&Tricks Bash tips and tricks - MandrivaUsers.org

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Tips&Tricks Bash tips and tricks

#1 User is offline   aru 

  • Mandriva Guru
  • Group: Members
  • Posts: 2,150
  • Joined: 04-December 02

Posted 15 January 2003 - 12:21 AM



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).
The text you've read above is supposed to be in english;
oops! btw, the code in this post -if any- is released under the GNU GPL v2 or later, that means among other things that it hasn't any warranty.


- The Unix philosophy in one lesson: KEEP IT SIMPLE, STUPID! -- ES. Raymond. "TAOUP"

You might want to take a look to our Musb FAQs and to "THE" FAQs... and remember "/usr/bin/man" is your best friend, use it!

:wq
0

#2 Guest_anon_*

  • Group: Guests

Posted 31 March 2004 - 08:12 PM

*Bump*
0

#3 User is offline   !nkubus 

  • frequent
  • Group: Members
  • Posts: 171
  • Joined: 03-November 03

Posted 31 March 2004 - 08:44 PM

i love the CDPATH on it's very usefull.

all of the others are quite useful to :)

thanks :)
0

#4 User is offline   aRTee 

  • Mandriva Guru
  • Group: Members
  • Posts: 2,216
  • Joined: 08-November 02

Posted 31 March 2004 - 09:12 PM

Noticed the directory tricks; give this a try:
when in a dir somewhere you realise you want to go back to the previous one:

cd -


Enjoy :P
System specs.

Mandrake/Mandriva linux tips 4 free

"You can do things with a computer with a graphical user interface (GUI),
whereas a computer with a command line interface (CLI) can do things for you." - aRTee, May 2008
0

#5 User is offline   Steve Scrimpshire 

  • This is a dark ride
  • Group: OTW
  • Posts: 3,590
  • Joined: 13-December 02

Posted 02 December 2004 - 06:12 AM

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?
Posted Image
0

#6 User is offline   theYinYeti 

  • Mandriva Guru
  • Group: Members
  • Posts: 2,125
  • Joined: 23-September 02

Posted 02 December 2004 - 08:25 AM

IMO, the command should end like that:
'{}'" \;
that is: remove the ; from inside the quotes, and add it escaped after them.

Yves.

This post has been edited by theYinYeti: 02 December 2004 - 08:27 AM

0

#7 User is offline   iphitus 

  • Arch Linux Developer, Rocket Scientist
  • View blog
  • Group: Global Moderator
  • Posts: 3,868
  • Joined: 16-April 03

Posted 02 December 2004 - 12:35 PM

oooh awesomeage
0

#8 User is offline   aru 

  • Mandriva Guru
  • Group: Members
  • Posts: 2,150
  • Joined: 04-December 02

Posted 02 December 2004 - 01:11 PM

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)' '{}' '{}' \;


"ME" said:

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

This post has been edited by aru: 02 December 2004 - 01:13 PM

The text you've read above is supposed to be in english;
oops! btw, the code in this post -if any- is released under the GNU GPL v2 or later, that means among other things that it hasn't any warranty.


- The Unix philosophy in one lesson: KEEP IT SIMPLE, STUPID! -- ES. Raymond. "TAOUP"

You might want to take a look to our Musb FAQs and to "THE" FAQs... and remember "/usr/bin/man" is your best friend, use it!

:wq
0

#9 User is offline   theYinYeti 

  • Mandriva Guru
  • Group: Members
  • Posts: 2,125
  • Joined: 23-September 02

Posted 02 December 2004 - 02:08 PM

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.

This post has been edited by theYinYeti: 02 December 2004 - 02:10 PM

0

#10 User is offline   aru 

  • Mandriva Guru
  • Group: Members
  • Posts: 2,150
  • Joined: 04-December 02

Posted 02 December 2004 - 05:41 PM

cool and twisted :mr-green:
The text you've read above is supposed to be in english;
oops! btw, the code in this post -if any- is released under the GNU GPL v2 or later, that means among other things that it hasn't any warranty.


- The Unix philosophy in one lesson: KEEP IT SIMPLE, STUPID! -- ES. Raymond. "TAOUP"

You might want to take a look to our Musb FAQs and to "THE" FAQs... and remember "/usr/bin/man" is your best friend, use it!

:wq
0

#11 User is offline   adamw 

  • Mandriva Guru
  • View blog
  • Group: Members
  • Posts: 2,327
  • Joined: 18-August 04

Posted 02 December 2004 - 08:09 PM

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?
Adam Williamson | http://www.happyassassin.net
Mandriva contributor and monkey-at-large
Feed the monkey: donate to help me work on Mandriva full-time
awilliamson A T mandriva D 0 T org
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users