ru Русский

Reticularium

NETWORKS PLACE

Well, quite self-explanatory. Only Bash and Ruby. Options “folder” and “file” are examples, replace them with what you need… Shared in hope this can help someone.

Bash template:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#!/usr/bin/env bash

possible_options="folder, file"
necessary_options="file"

# The 3 lines below are needed if the script needs other files located in the same folder.
# This finds the real folder even if the script is symlinked.
[ -h $0 ] && xcommand=`readlink $0` || xcommand=$0
rcommand=${xcommand##*/}   # The real script
rpath=${xcommand%/*}   # The real folder
# Replace the message below with appropriate usage info"
[ "X$*" == "X" ] && echo "Can't run without options. Possible options are: ${possible_options}" && exit 1

IFS1=$IFS
IFS='--'
for s_option in "${@}"
do
  found=0
  case ${s_option} in
  --*=*)
    s_optname=`expr "X$s_option" : 'X[^-]*-*\([^=]*\)'`  
    s_optarg=`expr "X$s_option" : 'X[^=]*=\(.*\)'` 
    ;;
  --*)
    s_optname=`expr "X$s_option" : 'X[^-]*-*\([^=]*\)'`    
    s_optarg='yes' 
    ;;
  *=*)
    echo "Wrong syntax: options must start with a double dash"
    exit 1
    ;;
  *)
    s_param=${s_option}
    s_optname=''
    s_optarg=''
    ;;
  esac

  for option in `echo $possible_options | sed 's/ /--/g'`; do 
    [ -n "$s_optname" ] && [ "X$s_optname" == "X$option" ] && eval "$option=\"${s_optarg}\"" && found=1
  done
  [ "X$s_option" == "X$s_param" ] && found=1
  if [[ found -ne 1 ]]; then 
    echo "Unknown option: $s_optname"
    exit 1
  fi
done
found=0

for option in `echo $necessary_options | sed 's/,//g'`; do
  [ "X$(eval echo \$$option)" == "X" ] && missing_options="${missing_options}, --${option}" && found=1
done
if [[ found -eq 1 ]]; then
  missing_options=${missing_options#*,}
  echo "Necessary options: ${missing_options} not found"
  exit 1
fi
IFS=$IFS1


### Here goes your code
#echo "option folder: ${folder}"
#echo "option file: ${file}"
#echo "parameter: ${s_param}"

Ruby template:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#!/usr/bin/env ruby

possible_options = "folder, file"
necessary_options = "file"
options = Hash.new
possible_options.split(',').each { |po| options[po.strip] = '' }
File.symlink?(__FILE__) ? xcommand = File.readlink(__FILE__) : xcommand = File.expand_path(__FILE__)
rcommand = File.basename(xcommand)
rpath = File.dirname(xcommand)
begin
  if ARGV.empty?
    # Replace the message below with appropriate usage info"
    raise(ArgumentError, "Can't run without options. Possible options are: #{possible_options}")
  else
    for s_option in ARGV
      ((s_option =~ /^--/).nil? and not (s_option =~ /=/).nil?) and raise(ArgumentError, "Wrong syntax: options must start with a double dash")
      ((s_option =~ /^--/).nil? and (s_option =~ /=/).nil?) and s_param = s_option
      (s_option =~ /=/).nil? ? s_optarg = "yes" : s_optarg = s_option.split("=")[1]
      s_optname = s_option.split('=')[0].gsub('--','')
      if options.include?(s_optname)
        options[s_optname] = s_optarg
      else
        if not s_param == s_optname
          raise(ArgumentError, "Unknown option: #{s_optname}")
          exit 1
        end
      end
    end
    necessary_options.split(',').each do |o|
      if options[o.strip].empty?
        raise(ArgumentError, "Option --#{o.strip} is necessary")
        exit 1
      end
    end
  end

### Here goes your code
### note that command-line options are in hash! Address them as e.g. options["file"]
#puts "option folder: #{options["folder"]}"
#puts "option file: #{options["file"]}"
#puts "parameter: #{s_param}"

rescue Exception => e
#  puts e.backtrace
  puts e.message
  exit 1
end

I’d only recommend to expand usage/help information.

Update: you can use method path instead of expand_path if it’s supported by your Ruby version.

Update: modified shell template, allowing arguments with spaces, but without non-option parameters:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#!/usr/bin/env bash

possible_options="folder, file"
necessary_options="file"

# The 3 lines below are needed if the script needs other files located in the same folder.
# This finds the real folder even if the script is symlinked.
[ -h $0 ] && xcommand=`readlink $0` || xcommand=$0
rcommand=${xcommand##*/}   # The real script
rpath=${xcommand%/*}   # The real folder
# Replace the message below with appropriate usage info"
[ "X$*" == "X" ] && echo "Can't run without options. Possible options are: ${possible_options}" && exit 1

ARGV=`echo ${@} | sed 's/^--//' | sed 's/ --/|/g'`

IFS1=$IFS
IFS='|'
for s_option in $ARGV
do
  s_optname=${s_option%%=*}
  s_optarg=${s_option##*=}
  [ "X$s_optarg" == "X$s_optname" ] && s_optarg="yes"
  for option in `echo $possible_options | sed 's/,//g'`; do 
    [ "X$s_optname" == "X$option" ] && eval "$s_optname=\"$s_optarg\"" && found=1
  done
  if [[ found -ne 1 ]]; then 
    echo "Unknown option: $s_optname"
    exit 1
  fi
done
IFS=$IFS1

found=0
for option in `echo $necessary_options | sed 's/ /|/g'`; do
  [ "X$(eval echo \$$option)" == "X" ] && missing_options="${missing_options}, --${option}" && found=1
done
if [[ found -eq 1 ]]; then
  missing_options=${missing_options#*,}
  echo "Necessary options: ${missing_options} not found"
  exit 1
fi

### Here goes your code
#echo "option folder: ${folder}"
#echo "option file: ${file}"
#echo "parameter: ${s_param}"

Comment it: