How to Find and Delete Empty Directories and Files in Unix


Question: How do I locate empty directories that doesn’t contain any files? Also, how do I find all empty files ( zero byte files ) in Linux? Answer: You can use unix find command to get a list of all empty files and directories as explained below. Also, refer to our earlier articles about unix find command [...]

Read More: How to Find and Delete Empty Directories and Files in Unix


Copyright ©
The Geek Stuff. All Rights Reserved. Support us when you shop at amazon. Thank You!

Get your copy of Vim 101 Hacks eBook.
Linux 101 Hacks eBook Password: linux-is-wonderful


AWK Arrays Explained with 5 Practical Examples


Awk programming language supports arrays. As part of our on-going awk examples series, we have seen awk user defined variables and awk built-in variables. Arrays are an extension of variables. Arrays are variable that hold more than one value. Similar to variables, arrays also has names. In some programming languages, arrays has to be declared, [...]

Read More: AWK Arrays Explained with 5 Practical Examples


Copyright ©
The Geek Stuff. All Rights Reserved. Support us when you shop at amazon. Thank You!

Get your copy of Vim 101 Hacks eBook.
Linux 101 Hacks eBook Password: linux-is-wonderful


How to Convert Text Document to Speech on Ubuntu Using eSpeak

Ubuntu espeak is a speech synthesizer for English (and several other languages) which will convert text to speech. You can straight away execute espeak command on your Ubuntu machine without any installation or configuration. In this article, let us review 8 examples of espeak command. espeak Example 1: Speak the words specified in command line This is the default [...]

Read More: How to Convert Text Document to Speech on Ubuntu Using eSpeak


Copyright ©
The Geek Stuff. All Rights Reserved. Support us when you shop at amazon. Thank You!

Get your copy of Vim 101 Hacks eBook.
Linux 101 Hacks eBook Password: linux-is-wonderful


How to Open Multiple Websites (tabs) in Firefox during Startup?

Question: How do I set multiple home pages in firefox? i.e I would like to open more than one website automatically when the firefox starts. Answer: Please follow the steps mentioned below to open multiple tabs in Firefox during startup. Step 1: Go to Firefox Options Window Go to: Tools menu -> Option menu-item -> Main Tab. Step 2: [...]

Read More: How to Open Multiple Websites (tabs) in Firefox during Startup?


Copyright ©
The Geek Stuff. All Rights Reserved. Support us when you shop at amazon. Thank You!

Get your copy of Vim 101 Hacks eBook.
Linux 101 Hacks eBook Password: linux-is-wonderful


Flashback 2004: Too much about perl and regexp

Continuing the flashback series. Here's 2004.

Still in school. Hacking on countless projects in perl.

While writing a command-line interpreter, I wanted you to be able to type 'st' or 'sta' instead of 'status' and have the code find a best match for your command. This is often called 'ambiguous commands' or somesuch. I came up with a clever way to do this using regular expressions (May 2004).

I also posted about using regular expression to match quoted and nonquoted strings (June 2004).

Finally, I experiment with using regular expressions to find word boundaries near the cursor for my command line interpreter (Oct 2004).

Are you drowning in perl and regular expressions, yet? ;)

Making iptables changes atomically and not dropping packets.

I'm working on rolling out iptables rules to all of our servers at work. It's not a totally simple task, as many things can go wrong.

The first problem is the one where you can shoot yourself in the foot. Install a new set of rules for testing on a remote server, and suddenly your ssh session stops responding. I covered how to work around that in a previous post.

Another problem is ensuring you make your firewall changes atomically. All rules pushed in a single step. In linux, if you have a script with many lines of 'iptables' invocations, running it will make one rule change per iptables command. And what if you write your rules like this?

# Flush rules so we can install our new ones.
iptables -F

# First rule, drop input by default
iptables -P INPUT DROP

# Other rules here...
iptables -A INPUT ... -j ACCEPT
iptables -A INPUT ... -j ACCEPT
If your server is highly trafficked, then the delay between the 'DROP' default and accept rules can mean dropped traffic. That sucks. This is an example of a race condition. Additionally, there's a second race condition earlier in the script where, depending on the default rule for INPUT, we may drop or accept all traffic for a very short period. Bad.

One other problem I thought could occur was a state tracking problem with conntrack. If previously we weren't using conntrack, what would happen to existing connections when I set default deny and only allowed connections that were established? Something like this:

iptables -P INPUT DROP
iptables -A INPUT -i eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 22 --syn -j ACCEPT
I did some testing with this, and I may be wrong here, but it does not drop my existing sessions as I had predicted. This is a good thing. Turns out, when this runs, the 'conntrack' table is populated with existing connections from the network stack. This further helps us not drop traffic when pushing new firewall rules. You can view the current conntrack table in the file /proc/net/ip_conntrack.

What options do we have for atomically applying a bunch of rules so we don't drop traffic? The iptables tool set comes with 'iptables-save' which lets you save your existing iptables rules to a file. I was unable to find any documentation on the exact format of this file, but it seems easy enough to read. The output includes rules and counters for each table and chain. Counters are optional.

All the documentation I've read indicates that using 'iptables-restore' will apply all of the rules atomically. This lets us set a pile of rules all at once without any race conditions.

So I generate an iptables-restore file and use iptables-restore to install it. No traffic dropped. I'm generating it with a shell script, so there was one gotcha - I basically take iptables commands and output them to a file. I do this with a shell function I wrote, called 'addrule'. However, I have some rules like this:

addrule -A INPUT -p tcp -m limit --limit 5/min -j LOG --log-prefix "Denied TCP: " --log-level debug
I quoted the argument in the addrule invocation, but we need to also produce a quoted version in our iptables-restore rule file, otherwise --log-prefix will get set to 'Denied' and we'll also fail because 'TCP:' is not an option iptables expects. It appears to be safe to quote all arguments in the iptables-restore files except for lines declaring chain counters (like ':INPUT ACCEPT [12345:987235]'), defining tables (like '*filter'), or the 'COMMIT' command. Instead of quoting everything, I just quote everything with spaces in an argument.

The fix makes my 'addrule' function look like this:

rulefile="$(mktemp)"

addrule() {
  while [ $# -gt 0 ] ; do
    # If the current arg has a space in it, output "arg"
    if echo "$1" | grep -q ' '  ; then
      echo -n "\"$1\""
    else
      echo -n "$1"
    fi
    [ $# -gt 1 ] && echo -n " "
    shift
  done >> $rulefile
  echo >> $rulefile
}

# So this:
#   addrule -A INPUT -j LOG --log-prefix "Hello World"
# will output this to the $rulefile
#   -A INPUT -j LOG --log-prefix "Hello World"
So now the quoted arguments stay quoted. All of that madness is in the name of being able to simple replace 'iptables' with 'addrule' and you're good to go. No extra formatting changes necessary.

One last thing I did was to make sure iptables-restore didn't reject my file, and if it did, to tell me:

if iptables-restore -t $rulefile ; then
  echo "iptables restore test successful, applying rules..."
  iptables-restore -v $rulefile
  rm $rulefile
else
  echo "iptables test failed. Rule file:" >&2
  echo "---" >&2
  cat $rulefile >&2
  rm $rulefile
  exit 1
fi
Throw this script into puppet and we've got automated firewall rule management that won't accidentally drop traffic on rule changes.

Bash Scripting Introduction Tutorial with 5 Practical Examples

Similar to our on-going Unix Sed and Unix Awk series, we will be posting several articles on Bash scripting, which will cover all the bash scripting techniques with practical examples. Shell is a program, which interprets user commands. The commands are either directly entered by the user or read from a file called the shell script. Shell [...]

Read More: Bash Scripting Introduction Tutorial with 5 Practical Examples


Copyright ©
The Geek Stuff. All Rights Reserved. Support us when you shop at amazon. Thank You!

Get your copy of Vim 101 Hacks eBook.
Linux 101 Hacks eBook Password: linux-is-wonderful


New keynav release available (0.20100302)

It's time for a new keynav release. The main push for this release was to fix problems with building against the new libxdo (xdotool) versions.

Additionally, there is one new feature: "record"

Recording lets you record a series of actions in keynav and replay them later much like you would in vim. Only keynav actions are recorded.

0.20100302.*:
  - Started using glib for dynamic arrays (GPtrArray)
  - Uses new versioning scheme major.date.svnrev
  - Added 'version' (or -v or --version) to output the keynav version
  - Now requires libxdo.so.1 (via xdotool)
  - Add ability to record keynav actions with the 'record' command. Optional argument
    is a filename to save the recordings to for persistence across keynav runs.
    Example in keynavrc to bind 'q' to record to ~/.keynav_macros:
      q record ~/.keynav_macros
    Works similar to vim recording.
      1) Hit record once
      2) Type the key you want to record to
      3) Do things in keynav you want recorded.
      4) Any 'end' operation or hitting record again will terminate and save
         this recording.
    Recordings only persist if you specify a file to save to, otherwise they are lost
    across keynav restarts.

20091231.04:
  - Try repeatedly to grab the keyboard with XGrabKeyboard on 'start' commands.
    This loop is a necessary workaround for programs like xbindkeys that could
    launch keynav but at the time of launch still hold a keyboard grab
    themselves. Reported by Colin Shea.

20091231.02:
  - Nonfunctional bug fixes and other code cleanup from patches by Russell Harmon