Bash script to truncate subject line of incoming email I'm going to put this script into production in a mail server /etc/aliases file: we have a system that receives email but the subject line must be limited to a certain size. The proposed usage in the aliases file:

alias_name: "| email_filter.sh -s 200 actual.recipient@example.com"


It will be deployed on a gnu/linux system. I'd appreciate any feedback.

#!/bin/bash
shopt -s extglob

usage="$(basename $BASH_SOURCE) [-h] [-s n] recipient"
where="where: -s n == truncate the subject to n characters"
subject_length=''

while getopts :hs: opt; do
    case $opt in
        h) echo "$usage"; echo "$where"; exit ;;
        s) subject_length=$OPTARG ;;
        *) echo "Error: $usage" &gt;&amp;2; exit 1 ;;
    esac
done
shift $((OPTIND - 1))

# validation
if [[ "$#" -eq 1 ]]; then
    recipient=$1
else
    echo "Error: $usage" &gt;&amp;2
    exit 1
fi
if [[ -n $subject_length ]] &amp;&amp; [[ $subject_length != +([0-9]) ]]; then
    echo "Error: subject length must be a whole number"
    exit 1
fi

sed_filters=()
if [[ -n $subject_length ]]; then
    sed_filters+=( -e "s/^(Subject: .{1,$subject_length}).*/\1/" )
fi
# other filters can go here

if [[ ${#sed_filters[@]} &gt; 0 ]]; then
    cmd=( sed -E "${sed_filters[@]}" )
else
    # no command line filters given
    cmd=( cat )
fi

# now, filter the incoming email (on stdin) and pass to sendmail
"${cmd[@]}" | /usr/sbin/sendmail -oi "$recipient"
Be sure to read the relevant RFCs that govern e-mail headers!  Specifically:


RFC 2822, Section 1.2.2: Header names are case-insensitive.
RFC 2822, Section 2.2.3: Header fields may be line-folded:


  2.2.3. Long Header Fields
  
  Each header field is logically a single line of characters
  comprising the field name, the colon, and the field body.  For
  convenience however, and to deal with the 998/78 character
  limitations per line, the field body portion of a header field can
  be split into a multiple line representation; this is called
  "folding".  The general rule is that wherever this standard allows
  for folding white space (not simply WSP characters), a CRLF may be
  inserted before any WSP.  For example, the header field:

Subject: This is a test

  
  can be represented as:

Subject: This
 is a test



Since your sed operates on the raw representation of the header, you will miss headers that are logically longer than subject_length characters long, but start with a physically short line.

What is your rationale for developing this filter?  Is the application that processes the incoming messages unable to handle long subject texts, or is it unable to handle long physical lines?  If it's the latter, maybe all you need is a filter that performs line folding, rather than truncation.
RFC 2047: Encoding mechanisms for non-ASCII headers.  A logical subject line

Subject: this is some text


… could also be represented physically as

Subject: =?iso-8859-1?q?this=20is=20some=20text?=


… or by many other representations.  Is your limit based on the number of bytes in the raw representation, the number of bytes in the UTF-8 representation, the number of Unicode characters, or something else?  You didn't specify clearly.  If you are truncating the raw representation, you might truncate a MIME-encoded header at a point that makes it syntactically invalid.