Jump to content


Photo
* * * * * 3 votes

Shell tricks


  • Please log in to reply
83 replies to this topic

#1 Octal

Octal

    Dangerous free thinker

  • Members
  • 886 posts

Posted 28 January 2007 - 08:34 PM

I made this thread as a basic resource for people, like newbie hq. But this is based on intresting/time saving/etc ways to use a shell in unix.

I'll start off the list:

The ; command

Character: semi colon - ;
Command: New line/command. Linking commands together
usage:
mkdir dir; cd dir
That would make the directory dir, then you would cd into the directory dir.

You can do some more. And remember to give a good explination.

#2 livinded

livinded

    Dangerous free thinker

  • Agents of the Revolution
  • 1,942 posts
  • Location:~/

Posted 28 January 2007 - 08:37 PM

The one thing that you need to keep in mind with ";" is that it will run all the commands regardless of how the program exists. If a command relies on another make sure that you use "&&" instead.

And for my trick:
"cat /dev/cdrom > ~/cdrom.iso"
You can use this for making isos of a cd that you have in the cdrom.

#3 Ohm

Ohm

    I could have written a book with all of these posts

  • Members
  • 3,209 posts
  • Gender:Male
  • Location:Maine, USA

Posted 28 January 2007 - 09:24 PM

First, you need to be a bit careful with what you call a "command". The ; character is not a command, rather a syntax element involved only in the parsing of a command-line. You also need to be careful and specify which are buitins and which are actual commands. For example, the cd command is a builtin, and cannot exist as a program launched by bash. If you were to put mkdir and cd together in a script with a shebang, the cd would work but since it's a builtin in a subshell, you'll still be in the same directory when the script exits.

So let's get alias and function down, those are useful for small scripts involving builtins. They appear to do the same thing, but functions are more flexible as they can take arguments and easily have multiple lines.

An alias is great for a shortcut. A common one is ll, being short for ls -l. That would be done with alias like this: alias ll='ls -l' You can then put that in your startup scripts, so you have it in all your shells. It's very limited though, as it can't take arguments and the syntax is very inflexible.

A function is better for a utility function, small script or reusable piece of code. To create a directory and cd to it in a function, it would look something like this:
function mkcd {
  mkdir "$1"
  cd "$1"
}

First see that its syntax is much better than an alias, especially for more complex actions. Second, see that an argument is used here. The $1 variable is expanded to the first argument passed to the function. Remember to always quote your expanded variables, mkdir some dir is much different than mkdir "some dir" and without the quotes, an argument with a space will expand to the first.

Using these to simplify complex tasks is a lifesaver if you use complex commands. For example, I need to encode some video, and if you've ever used a command-line video encoder (like mencoder or ffmpeg), you know that they take a million argument and they can be hard to get right. So, I put them in function in a file in my ~/scripts directory. When I want to get access to them (since I don't like to autoload so many functions), I just load it with . ~/scripts/encode. Then I have access to all my video encoding functions.

And how about the for loop? I use this a lot, especially in a task like mass renaming. Here's a quick example, I want to copy all png files to ~/backup, but not if it already exists there.
for f in *.png; do
  if [ ! -f ~/backup/"$f" ]; then  cp "$f" ~/backup/"$f";  fi
done

That's pretty useful, especially since you can mangle the filenames however you want (add a .bak extension, for example). But there's one thing to watch out for, it won't work if there's spaces in the filename. I use a slightly different loop for something like that, along with a pipe.
ls *.png | while read f; do
  if [ ! -f ~/backup/"$f" ]; then  cp "$f" ~/backup/"$f";  fi
done
Just remember to watch out for spaces in your filenames and always quote your variable expansions.

#4 Octal

Octal

    Dangerous free thinker

  • Members
  • 886 posts

Posted 29 January 2007 - 04:00 PM

Ohm, I have always been 'anti' on aliases. They teach you commands that only work on your system. This shouldn't be a problem, but if you are helping somone with a problem, or writing a tutorial, you could just say, "then type ll and see what comes out.", instead of "Type ls -l and see what comes out.". Its good to have an alias for some commands though, as long as you know what they exactly do, know how they work, and so on.

I really shouldn't have said that because someone will probaly say things about how I'm wrong, and then this thread will get off-topic.

Some more tricks:

ctrl+c
Lets say you where compiling a program, and typed ./config. You realized that you wanted to stop the ./config half way through. This will work for that. Just press ctrl+c (you don't press the plus button), and you will have a prompt back.

ctrl+alt+f1 ctrl+alt+f2 ctrl+alt+f3 ctrl+alt+f4 ctrl+alt+f5 ctrl+alt+f6
All full screen terminals.

ctrl+alt+f7
Get to GUI after in full screen terminal.

I'll put more as I think of them.

#5 Alk3

Alk3

    "I Hack, therefore, I am"

  • Binrev Financier
  • 1,003 posts
  • Gender:Not Telling
  • Location:312 Chi-town

Posted 29 January 2007 - 06:12 PM

To write an executable script, you must make it executable with 'chmod.' A script will allow you to automate tasks with minimal efforts. So, to make an executable script open up your favorite text editor (ie gEdit, nano, vim, kate, mousepad) and insert the desired commands (or even aliases). Once you have it written, save it, and then you must 'chmod' like so:
user@localhost:~$ chmod +x scriptname

Where scriptname is the title of the script and chmod must be run as the user you want to use when you run the script. If you chmod as root, then the script will only be executable by root etc etc. However, even though a script has the correct permissions for the desired user, you may still need to be root to run specific commands that are only accessible by the super user.

On a side note:
user@localhost:~$ rm -r filename/directory
will remove the file/directory recursively. Use this sparingly, IMO, since you may accidentally delete files that you need PERMANENTLY. Depending on file permissions, you can only remove files that are controlled by you...

Here is an example on applying a command to ALL files in the directory:
user@localhost:~$ rm -r *
Where * is saying to the computer to apply the command to ALL available directories/files. Note: never use this in the / directory or even at all if you are not sure what you will be applying to. Depending on file permissions, you can only remove files that are controlled by you...

Alk3

I will add more when I get time. :voteyes:

#6 Octal

Octal

    Dangerous free thinker

  • Members
  • 886 posts

Posted 29 January 2007 - 07:33 PM

Alk3, doesn't chmod 700 [scriptname] work too? Thats what I always use.

#7 pbx43k

pbx43k

    Mack Daddy 31337

  • Members
  • 241 posts

Posted 30 January 2007 - 02:19 AM

I'm sure its been covered before, but one of the most life-saving terminal tools is screen

Screen is a full-screen window manager that multiplexes a physical terminal between several processes, typically interactive shells. Each virtual terminal provides the functions of the DEC VT100 terminal and, in addition, several control functions from the ANSI X3.64 (ISO 6429) and ISO 2022 standards (e.g., insert/delete line and support for multiple character sets). There is a scrollback history buffer for each virtual terminal and a copy-and-paste mechanism that allows the user to move text regions between windows. When screen is called, it creates a single window with a shell in it (or the specified command) and then gets out of your way so that you can use the program as you normally would. Then, at any time, you can create new (full-screen) windows with other programs in them (including more shells), kill the current window, view a list of the active windows, turn output logging on and off, copy text between windows, view the scrollback history, switch between windows, etc. All windows run their programs completely independent of each other. Programs continue to run when their window is currently not visible and even when the whole screen session is detached from the users terminal.


screen allows you to run multiple virtual terminals within a single physical terminal. You can page between different terminal and even keep processes running after detaching from a virtual terminal. For people like me who bring their work home with them, its a great tool, as you can leave a long-running process going, log out of a server, then reattach to the terminal from a different location.

This is also good while working on a server with a flaky network adapter or in a location where your connection is not very stable. Few things are more annoying than having a large remote tar job stop at 94% because your local network takes a dive.

Edited by pbx43k, 30 January 2007 - 02:21 AM.


#8 Ohm

Ohm

    I could have written a book with all of these posts

  • Members
  • 3,209 posts
  • Gender:Male
  • Location:Maine, USA

Posted 30 January 2007 - 02:31 AM

Alk3, doesn't chmod 700 [scriptname] work too? Thats what I always use.


chmod is something you need to learn how to use correctly. First understand that it has 2 modes of operation. The absolute mode (like 700) is pretty error-prone. Don't use it unless you're absolutely sure you want to set every permission bit. In this case, you probably don't want to do that. There is also the risk of mis-reading the existing bits, and trying to reconstitute them on the command line, accidentally setting or clearing bits that shouldn't be changed. The second mode is symbolic mode, and it's a lot more human friendly. If I wanted to set the execute bit for my user, I could say something like chmod u+x file. I don't have to worry about which other bits are set, I can just specify which bits I want to be set. The man page has all the info, definitely read it carefully.

chmod is only of the most abused commands. Don't be ignorant like the rest, RTFM and use it competently!

#9 Dirk Chestnut

Dirk Chestnut

    SUP3R 31337 P1MP

  • Members
  • 268 posts
  • Location:248

Posted 30 January 2007 - 07:34 AM

chmod is only of the most abused commands. Don't be ignorant like the rest, RTFM and use it competently!


Ugh, I don't want to talk about all the times I've seen some jackass dev get in a hurry, and chmod -R 777 an entire /var/www directory... All it takes is one time doing that, and the security of your system can be seriously compromised.

Back on topic:

I'm a huge fan of Background and foreground jobs. Not need to open multiple terminal emulators, or use a bunch of console logins!

Say you run:

[root@localhost ~]# updatedb

This command can take quite a few minutes to complete. If you want to send it to the background, while it's running you press Ctrl+Z, to pause the command. Then, at the new command prompt you enter:

[root@localhost ~]# bg

You'll see an output similar to "[1]+ Running updatedb &" The job is now in the background and running again, so the terminal is free for more commands. Notice the "[1]" part, this tells you your job number. If you forgot it, you could enter the command "jobs" at the command line and see a list of suspended or running. Note that you can start a command as a background job by appending "&" to the end of a command before you press enter, it will be running in the background automatically.

You could bring a job to the foreground by entering the command:

[root@localhost ~]# fg %1

Where % tells the fg command to expect a job number, and 1 represents the job number to bring to the foreground. If you wanted to kill the job, you could then do a good old fashioned Ctrl+C.

If you allow a job in the background to run, it will exit silently and (by default) the line "[1]+ Done" will only pop up in the shell when you press enter.

The only thing to recognize about this, is if you send a job to the background, and that job is going to generate output (ex- the find command), that output will automatically be sent to the console, and it's a pain to try to key in commands as text randomly pops up on screen. You could always start a command like find in the background with "find -name 'somestring' > somefile &", which would redirect all output to a file for later viewing.

Edited by Dirk Chestnut, 30 January 2007 - 07:36 AM.


#10 jfalcon

jfalcon

    Hakker addict

  • Agents of the Revolution
  • 593 posts
  • Location:Living within the ether

Posted 30 January 2007 - 07:46 AM

'man' is the man.

RTFM FTW!

Pipes and Regular Expressions would be high on my list of "tricks" to learn.
For instance, using RegEx with sed to remove DOS CR/LF's:
cat dostextfile.txt | sed 's/.$//' > unixtextfile.txt

http://www.student.n...ed/sed1line.txt

#11 Dirk Chestnut

Dirk Chestnut

    SUP3R 31337 P1MP

  • Members
  • 268 posts
  • Location:248

Posted 30 January 2007 - 07:59 AM

For instance, using RegEx with sed to remove DOS CR/LF's:
cat dostextfile.txt | sed 's/.$//' > unixtextfile.txt


Heh, not to undercut your plug for regexps (which are _REALLY_ useful. Don't skip the grep and sed sections of your favorite *nix noob docs), but I think you can do that with the "dos2unix" command.

#12 jfalcon

jfalcon

    Hakker addict

  • Agents of the Revolution
  • 593 posts
  • Location:Living within the ether

Posted 30 January 2007 - 08:14 AM

For instance, using RegEx with sed to remove DOS CR/LF's:
cat dostextfile.txt | sed 's/.$//' > unixtextfile.txt


Heh, not to undercut your plug for regexps (which are _REALLY_ useful. Don't skip the grep and sed sections of your favorite *nix noob docs), but I think you can do that with the "dos2unix" command.


Well, I would think it would fall into the "alias" category if you were to use dos2unix. Some distros don't have the dos2unix/unix2dos commands installed by default. But most systems have sed and cat. For instance a solaris box wouldn't have dos2unix.

But it shows you're thinkin! How about a Fresca?

#13 Alk3

Alk3

    "I Hack, therefore, I am"

  • Binrev Financier
  • 1,003 posts
  • Gender:Not Telling
  • Location:312 Chi-town

Posted 30 January 2007 - 03:58 PM

I agree with Ohm. chmod can be abused/misused very easily. If you are new to linux, and you are using a distribution that has a desktop environment, use the file manager. Most file managers make file permissions easy to manage.

Alk3

#14 Octal

Octal

    Dangerous free thinker

  • Members
  • 886 posts

Posted 30 January 2007 - 04:03 PM

You have to be in GUI for this though.

Open a software via command line:

There are a few ways. The most often used way is to just put an & at the end. So to start firefox:
firefox &
Though when you close the terminal, you close firefox.
or do this:
whereis firefox
lets say you get this:
firefox: /usr/bin/firefox /etc/firefox /usr/lib/firefox /usr/bin/X11/firefox /usr/share/firefox /usr/share/man/man1/firefox.1.gz
then cd into /usr/bin
cd /usr/bin
then execture firefox:
./firefox

This thread has some interesting information in it so far.

#15 Beave

Beave

    SUPR3M3 31337 Mack Daddy P1MP

  • Agents of the Revolution
  • 350 posts

Posted 30 January 2007 - 05:06 PM

The one thing that you need to keep in mind with ";" is that it will run all the commands regardless of how the program exists. If a command relies on another make sure that you use "&&" instead.

And for my trick:
"cat /dev/cdrom > ~/cdrom.iso"
You can use this for making isos of a cd that you have in the cdrom.


dd if=/dev/cdrom of=/tmp/my.iso... or (if not linked) dd=/dev/hd{} of=/tmp/my.iso.....

dd is useful for many things. It's also nice to use when recovering a drive with dd_rescue. You can dd_rescue hard drive images. Once complete, mount them to a loopback device. This is also a good idea for forensics. This way, you dont correct the orignal drive - you use a image of it. If you fuck up, no bigged, copy back the image and start over.

#16 xGERMx

xGERMx

    SUPR3M3 31337 Mack Daddy P1MP

  • Members
  • 459 posts

Posted 30 January 2007 - 09:20 PM

Okay, here is a quick one. While I'm sure this is nothing revolutionary for *nix vets, newbies (coming from windows) will find this very useful.
*Sorry Ohm, this also isn't a command...haha

Globbing - AKA tabbed completion
Example: If you trying to cd to /desktop/folderwithreallylongname just type cd/desktop/f [tab] and all files and directories in /desktop that start with the letter f will be available by pressing tab.
So if you have folders named folderA, folderB, FolderC, you could just press tab until folderwithreallylongname comes up or you can type folderw [tab] and only the files and directories starting with "folderw" will be available.

I know that this is a very simple but, there is no globbing in a Windows cmd, so this should be helpful to anyone migrating to Linux from WinDoors.

#17 jfalcon

jfalcon

    Hakker addict

  • Agents of the Revolution
  • 593 posts
  • Location:Living within the ether

Posted 30 January 2007 - 11:50 PM

I know that this is a very simple but, there is no globbing in a Windows cmd, so this should be helpful to anyone migrating to Linux from WinDoors.


There actually is in XP and 2003 (and Vista which released today).

#18 xGERMx

xGERMx

    SUPR3M3 31337 Mack Daddy P1MP

  • Members
  • 459 posts

Posted 31 January 2007 - 12:59 AM

I know that this is a very simple but, there is no globbing in a Windows cmd, so this should be helpful to anyone migrating to Linux from WinDoors.


There actually is in XP and 2003 (and Vista which released today).



Wow, total brain fart.
The reason I said that was because I went in to Command Prompt and typed cd tab and it didn't anything.
Only now do i see the error of my ways. Of course it works if you use the right command (i.e. dir instead of cd)

Basic tip #2 for newbies.

Bash History.
While in a terminal typing the command [i][history/i] will show a list of previously typed commands. You can also display previously typed commands by pressing the up arrow key.

(you can do this a windows cmd too....haha)

#19 Beave

Beave

    SUPR3M3 31337 Mack Daddy P1MP

  • Agents of the Revolution
  • 350 posts

Posted 31 January 2007 - 01:56 AM

Here's a easy, but useful one.. Say you have a large file (/var/log/messages)... you want to "zero" it out, but keep the file.. Type:

:> /var/log/messages

Done...

#20 chaostic

chaostic

    rekcah-rebÜ

  • Members
  • 724 posts

Posted 31 January 2007 - 03:26 AM

Okay, here is a quick one. While I'm sure this is nothing revolutionary for *nix vets, newbies (coming from windows) will find this very useful.
*Sorry Ohm, this also isn't a command...haha

Globbing - AKA tabbed completion
Example: If you trying to cd to /desktop/folderwithreallylongname just type cd/desktop/f [tab] and all files and directories in /desktop that start with the letter f will be available by pressing tab.
So if you have folders named folderA, folderB, FolderC, you could just press tab until folderwithreallylongname comes up or you can type folderw [tab] and only the files and directories starting with "folderw" will be available.

I know that this is a very simple but, there is no globbing in a Windows cmd, so this should be helpful to anyone migrating to Linux from WinDoors.


This depends on how the shell is set up. On OS X, normally, in your example, tab will complete f to folder, then beep. A second tab press will list all possible options similar to how ls lists files. Changing an option in your rc file can change it to cycle mode.

Now if there was an easy way to switch thru both modes...




BinRev is hosted by the great people at Lunarpages!