Category Archives: Command Line

bckfile—backup a file with sequential numbering

I have discovered over the years that protecting a file, its content, and developing in a controlled, deliberate method is usually something good to keep in mind. I have learned that if I feel an document, project… is important, then to backup the data and then do the edit is the methodology I need to learn.

When I decide to backup a file, first thing I do is to see if there is a _vault directory. In any location where I had to backup previously, I created this directory. After the first time I did this I realized I was going to have to number these file backups. I reasoned out that filename_[0-9][0-9] would be a format that would be sufficient, if there was an extension it would be filename_[0-9][0-9].ext.

As I could see that file backups were something that I would regularly do, I decided to create a script that would automate this task. It tests the destination directory if the file exists. For the first backup, the script prepends 00 to the file, after that its prepend the sequential number.

The usage is basic: I define the source file and optionally the destination directory. The current directory is assumed if only the source file is specified.

An example:

$ bckfile file.txt _vault
‘file.txt’ -> ‘_vault/file_01.txt’

The script does have one limitation: the filename can only contain one period and it must be for the extension. This is necessary as determination for an otherwise intention would take a lot of work 😊.

bckfile can be found in my general scripts repository.

gt—create a gedit scratchpad

geditmp—a-script-to-create-a-gedit-scratchpad

I am really lazy with my editors. I have aliases in my shell configuration for gedit and vim to open them as quickly as possible:

alias v="vim -p"
alias sv="sudo vim -p"
alias g="bgcmd gedit"
alias sg="bgcmd gksudo geany"

This is very nice for me because I use my editors quite a bit. One thing I needed though was a command that would create and open a temporary file in gedit. The main reason for this is that, there are times, I don’t know how to name or place the file properly yet. At other times, the reason is, I like to have a scratchpad that would save information that I might forget if it was just a new file and I forgot about it or a crash happened.

The bash script

Running gt will create and open a file named with the current time (MMDDhhmm) and will be saved in the trash folder. If gt is followed by a name (e.g. gt geditmp.md) the name will be appended to the time.

geditmp-example

The name is helpful if wanting to dig the file out of the trash folder at a later time.

#!/usr/bin/bash
# (g)edit (t)emp. file — create gedit scratchpad

tmp_dir=~/.local/share/Trash/files
tme_day=$(date +%m%d%H%M)

[ ! -d "$tmp_dir" ] && mkdir -pv "$tmp_dir"

# gedit existence test
hash gedit 2>&- || { echo "Requires program \"gedit\"."; exit 1; }

# Usage
if [ "$1" = -h -o "$1" = --help ]; then
  echo "${0##*/} [name1] [name2*] — create a gedit scratchpad"
  exit 2
fi

if [ "$1" ]; then
  for name in "$@"; do
    nohup gedit "$tmp_dir"/"$tme_day"-"$name" &> /dev/null &
  done
else
  nohup gedit "$tmp_dir"/"$tme_day" &> /dev/null &
fi

Write The Fine Manual with pod2man

Disclaimer: This is a guide for basic manual writing. It uses a simple markup language and converter to create a manual. It is good for beginners. For a good general overview of man pages read this, for more common approaches to writing manuals read this post.

An example

To get a good idea of how to write a manual seeing the markup of a POD (Perl’s Plain Old Document) works well. This is a POD for a fictitious program called dr-smile:


=encoding UTF8

=head1 NAME

dr-smile — output platitudes to help to improve one's mood

=head1 SYNOPSIS

dr-smile [B<--happy>] [B<--joke>=F<type>]

=head1 DESCRIPTION

B<dr-smile> outputs jokes and happy thoughts designed to make one feel F<--better>. It has the ability to output pleasant thoughts, jokes, good memories, optimistic fortunes, or just give you a big hub. B<dr-smile> is for I<entertainment> and for light mood change requirements. Please use responsibly and with greater change requirements please see an appropriate professional. Additional options are available in the configuration file F</etc/dr-smile.conf>.

=over 4

=item B<-h>B<--happy>

A general happy thought will be output (e.g. C<dr-smile --happy>).

=item B<-j> F<type>B<--joke>=F<type>

A good-sense joke will be told.  The types are: F<knock> and F<oddball>.  Read more in B<jokes(1)>.

=back

Text formatting

Man pages are mainly created with these types of formatting:

Format Markup
bold B<text>
italic I<text>
link L<http://address.domain >
file name F<file-name>
email E<name@address.domain>

Note: E<> is technically for escapes, however, I have seen it used before in another pod2man document—whether intentional or not I am not sure. Read the manual perlpod for markup information.

From a general observation over the years, bold and italic formatting get used in these situations:

Bold:

  • program names
  • options
  • other manuals

Italic:

  • keywords
  • emphasis
  • arguments
  • occasionally manuals

Category formatting

Manual page categories are generally formatted with a certain order. The order of categories vary a bit per man page but the first four are usually present. Here is the general structure and their purpose

NAME
  The name of the command followed by a one-line description of what it does.
SYNOPSIS
  A command's invocation with its listed options, or a functions parameter listings with its header file.
DESCRIPTION
  An in-depth explanation of the command or function.
OPTIONS
  A explanation(s) of what an option does these are sometimes put in the DESCRIPTION.
EXAMPLES
  Some examples of common usage.
FILES
  Files related to the command or function.
BUGS
  List of known bugs.
SEE ALSO
  A list of referenced or related commands.
AUTHOR, HISTORY, COPYRIGHT, LICENSE
  Information about the author...

For how to create the categorical entries, I only know the basic formatting. Look at the above example to see how it is done.

  • Category begin is defined with the head1 tag.
  • Indenting is done with the over 4 tag.\
  • Category item is defined with the =item tag.
  • Category end to define a new category is done with the =back tag.

Document to manual conversion

pod2man usage is basic. First look at manual section definitions here to know what section it should belong to. For my miscellaneous, fictitious program:

pod2man dr-smile.pod > dr-smile.7

Additional information may be wanted to add to the manual along with compression:

pod2man --section=7 --center="General Commands Manual" --release="1.0" \
dr-smile.pod | gzip > dr-smile.7.gz

To view the man page use man -l dr-smile.7.gz.

screenshot-manpage

Resources

xuserrun—run a command as the currently active X.org server user

xuserrun is a bash script to detect the first X.org server environmental values, these values are then used to transmit a command to it. The script is primarily useful from another environment: a different user, from the tty console, from cron, a boot script…. xuserrun requires systemd.

Running it is basic:

xuserrun xclock -digital

Another example:

xuserrun notify-send "Remember to get bread."

I have put it in its own repository.

Audio file encode to a video file

I wanted to convert an MP3 file to a video file to be able to use it on my PS3. The PS3 has an audio player but it doesn’t remember the position. It was an audiobook so it was best for me to convert it to a video file.

#!/usr/bin/bash
# Create video file from audio file.

# Required programs.
if ! hash ffmpeg 2>&- ; then
  echo "Requires program: ffmpeg"; exit 1; fi

# Usage.
if [ $# != 2 ] ; then
    echo "${0##*/} <image> <audio> - create video file from an audio file."
    exit 1; fi

# Files existent test.
if [ ! -f "$1" ] ; then
    echo "non-existent image: "$1""
    exit 1; fi
if [ ! -f "$2" ] ; then
    echo "non-existant audio: "$2""
    exit 1; fi

vid_nme="${2%.*}".mp4
ffmpeg -f image2 -loop 1 -i "$1" -i "$2" -c:v libx264 -tune stillimage 
  -c:a copy -strict experimental -shortest "$vid_nme"

#ffmpeg -f image2 -loop 1 -i "$1" -i "$2" -c:v libx264 -tune stillimage 
#  -c:a aac -strict experimental -b:a 192k -shortest "$3".mp4

Disk and Memory Usage Scripts

At times I like to check my levels of disk and memory usage and it’s more available for me at times for me to do it from the command line. Therefore, I created two scripts for them:

$ devtop 
Filesystem  Size  Used  Avail  Use%  Mounted
/dev/sda1   291G  101G  187G   36%   /
/dev/sda2   166G   38G  121G   24%   /home

$ memtop
PROGRAM          %MEM  #MEM
firefox          14.0  1049.7 MiB
gnome-shell      2.2   165.84 MiB
thunderbird      1.9   143.773 MiB
gedit            0.8   63.8555 MiB
nautilus         0.6   44.9961 MiB
Xorg             0.5   38.5039 MiB
gnome-terminal-  0.3   28.8164 MiB
keepassx         0.3   27.6406 MiB
tracker-extract  0.2   21.1992 MiB

Both script are part of my genscripts-git that is in the Arch Linux User Repository.

Regular videos convert for PSP viewing


I like to put videos on my PSP` to watch later. To be able to remember the options I put this in a bash script.

pspvidconv [-d*] <dir.*> <video(s)> — convert videos to PSP

The PSP allows the creation/use of a supplementary single-depth directory. The directory option (-d) will ask if the user wants to create a new directory, if the answer is no, it will present the existing folders.

#!/usr/bin/bash
# Convert videos to PSP

# Settings
vid_dir=/run/media/$USER/PSP/VIDEO  # For Gnome 3, Gnome 2: /media/PSP/VIDEO
vid_vcd="-vcodec mpeg4 -vtag xvid"  # Video codec: xvid
vid_vcd="-vcodec libx264"           # Video codec: x264
vid_vcd="-vcodec h264"
vid_res=320x240                     # 320x240 for PSP 1001, 480x272 for 2001
vid_vbr=768k                        # Video bit rate, was 1024
vid_vfr=29.97                       # Video frame rate
vid_acd=aac                         # Audio codec to use (libfaac for some)
vid_aab=64k                         # Audio bit rate
vid_aar=48000                       # Audio sampling frequency
vid_aac=2                           # Audio number of channels
fns_snd=/usr/share/sounds/alsa/Front_Center.wav

# Usage
if [[ -z "$@" ]]; then
  echo "${0##*/} [-d*] <dir.*> <video(s)> — convert videos to PSP"
  exit
fi

# Check that PSP is plugged in
if [ ! -d $vid_dir ]; then
  echo "It appears that the PSP is not plugged in, no "$vid_dir"."
  exit
fi

# Use sub-directory
if [ "$1" == "-d" ]; then
  while true; do
    read -p " Create a new directory? (y/n): " yn
    case $yn in
      [Yy] )  read -p " Directory name (no spaces): " newdir
              vid_dir="$vid_dir"/"$newdir"
              mkdir "$vid_dir" && break 2;;
      [Nn] )  printf " Select PSP VIDEO sub-directory:n"
              select vid_sub in "$vid_dir"/*/
                do
                  vid_dir="$vid_sub"
                  test -n "$vid_dir" && break 2
                  echo " Select 1, 2, ..."
                done ;;
      * )     echo " Answer (y)es or (n)o."
    esac
  done
  shift
fi

# Check if selection(s) exists
for vid in "$@"; do
  if [ ! -f "$vid" ]; then
    echo " Selection ""$vid"" does not exist."
    exit
  fi
done

# Convert, save to PSP video directory
for vid in "$@"; do
  vid_out="${vid/:/-}"            # ffmpeg not allowing outputs of ':', '?'
  vid_out="${vid_out/?/}"        # http://tinyurl.com/ffmpeg-filename-colon
  #vid_out="${vid_out%.*}"-PSP.mp4 # Append '-PSP' to filename
  thm_out="${vid_out%.*}".thm
  # Encode video
  ffmpeg -i file:"$vid" $(printf '%s' "$vid_vcd") -s "$vid_res" -b:v "$vid_vbr" -r "$vid_vfr" -acodec "$vid_acd" -b:a "$vid_aab" -ar "$vid_aar" -ac "$vid_aac" -f psp -strict -2 -y "$vid_dir"/"$vid_out"
  # Create thumbnail
  ffmpeg -i file:"$vid" -f image2 -ss 50 -vframes 1 -s 160x120 "$vid_dir"/"$thm_out"
done && aplay "$fns_snd"