Unix Tricks

This page will hold any random notes I have on various unix tools or tricks, mostly just as documentation for myself. If any topic here gets too big for one page, I'll just move it to its own page.

Cronjobs

Cronjob are for running periodic tasks. They are run per user.

To see your crontab:

crontab -l

To edit your crontab:

crontab -e

This will bring you into your configured editor (see your EDITOR environment variable).

Your crontab format looks like this:

# 1 Minute 0-59
# 2 Hour 0-23 (0 = midnight)
# 3 Day 1-31
# 4 Month 1-12
# 5 Weekday 0-6 (0 = Sunday) 
#
#0 */4 * * *       /home/dcr/sandbox/bin/backup_to_external.sh hourly
0 5 * * *       /home/dcr/sandbox/bin/backup_to_external.sh daily
0 3 * * 0       /home/dcr/sandbox/bin/backup_to_external.sh weekly
0 1 1 * *       /home/dcr/sandbox/bin/backup_to_external.sh monthly

Putting a "*" means "don't care" or "any". So this line:

0 5 * * *       /home/dcr/sandbox/bin/backup_to_external.sh daily

means 5 am every day because the other specified parts are "don't care". Putting a */4 in the hour column means "do this every 4 hours".

You can put a comma separated list of value for each column. For example, this line:

0,10,20,30,40,50 * * * * /home/drivet/sandbox/bin/syncvps.sh

means that we want to run the script at the hour, at the 10 minute mark, at the 20 minute mark, etc. In other words, we run the script every 10 minutes.

Diff and Patch

Good tutorial: http://stephenjungels.com/jungels.net/articles/diff-patch-ten-minutes.html

Most of this is taken from that.

diff and patch are two mirror operations. diff will produce a patch file while patch will apply one. Basically, just do this:

$ diff -rupN original/ new/ > patch.diff

original and new can be files or directories. So, if you download a source tree and you want to make some modifications, you can make a copy of the tree and edit the new copy. Then run the above command to produce a patch.

The r means recurse into subdirectories, the u means use unified format (required to use patch later), the p means show which C function each change is in and the N means treat absent files as empty.

To apply the patch, use this:

patch < patch.diff

Remember that patch.diff contains the files that need to be patched. At this point you have to be careful of p levels. For example, you could run the above command like this:

patch -p0 < patch.diff

Imagine that patch.diff looks like this:

diff -prNu original/lala.c new/lala.c
--- original/lala.c     2010-04-13 21:02:05.000000000 -0400
+++ new/lala.c  2010-04-13 21:02:36.000000000 -0400
@@ -1,2 +1 @@
 gggg
-dddd
diff -prNu original/stuff.c new/stuff.c
--- original/stuff.c    2010-04-13 21:01:54.000000000 -0400
+++ new/stuff.c 2010-04-13 21:02:23.000000000 -0400
@@ -1,2 +1,3 @@
 hello
 hehe
+zzzz

If the patch was produced as shown above, and you position yourself in the same directory as the original and new directories, then you supply a p number of 0, as in -p0. This tells patch to use the file names unaltered. A p level of 1 means to remove the first patch component. You would do this if the first part of the paths are not on your system. The man page says it best:

-pnum  or  --strip=num

Strip the smallest prefix containing num leading slashes from each file name found in the  patch  file.  A  sequence of one or more adjacent slashes is counted as a single slash.  This controls how file names found in the patch file are treated, in case you keep your files in a different directory than the person who sent out the patch.  For example, supposing the file name in the patch file was

       /u/howard/src/blurfl/blurfl.c

setting -p0 gives the entire file name unmodified, -p1 gives

       u/howard/src/blurfl/blurfl.c

without the leading slash, -p4 gives

       blurfl/blurfl.c

and not specifying -p at all just gives you blurfl.c.  Whatever you end up with is looked for either in the current directory, or the directory specified by the -d option.

Bash initialization

There are two files associated with bash initialization: .bash_profile and .bashrc. The .bash_profile is called whenever you start a login shell, while the .bashrc gets called whenever you start an non-login shell, say when you just call "bash" from the command line.

This means that you might see something strange if you set self-referencing bash variables in your .bashrc. Since it gets called every time you start a shell, the value can grow.

If you want the full nitty-gritty, here it is (alot of this is stolen from the bash man page):

When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and  executes commands  from  the  file /etc/profile, if that file exists.  After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable.  The --noprofile option  may be used when the shell is started to inhibit this behavior.

So.../etc/profile is used for system wide login setting, and .bash_profile (or .bash_login or .profile) is used for personal login settings.

On logout from a login shell, bash will execute .bash_logout.

Then:

When  an  interactive shell that is not a login shell is started, bash reads and executes commands from /etc/bash.bashrc and ~/.bashrc, if these files exist.  This may be inhibited by using the --norc option.  The --rcfile file option will force bash to read and  execute commands from file instead of /etc/bash.bashrc and ~/.bashrc.

So, /etc/bash.bashrc is used for system non-login settings. .bashrc is used for personal non-login settings. What's a bashrc file good for? Aliases, for one things.

With non-interactive shells (say, shells that are started just to run a shell script):

When  bash  is  started  non-interactively,  to run a shell script, for example, it looks for the variable BASH_ENV in the environment, expands its value if it appears there, and uses the expanded value as the name of a file to read and execute.  Bash behaves as  if  the following command were executed:
       if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi
but the value of the PATH variable is not used to search for the file name.

Display Managers

When logging in through a display manager, your .bash_profile isn't read. I think your $HOME/.xsession is read. When not using a display manager, your .xinitrc file is read. Most people just have one call the other.

UnixTricks (last edited 2012-05-18 01:36:29 by DesmondRivet)