argbash
argbash copied to clipboard
recursion: parse arguments from file
gcc has this option:
@file
Read command-line options from file. The options read are inserted in place of the original
@file
option. If file does not exist, or cannot be read, then the option will be treated literally, and not removed.Options in file are separated by whitespace. A whitespace character may be included in an option by surrounding the entire option in either single or double quotes. Any character (including a backslash) may be included by prefixing the character to be included with a backslash. The file may itself contain additional
@file
options; any such options will be processed recursively.
so the @my-args.txt
argument is expanded / replaced with the contents of the my-args.txt
file
my use case: i made my own parser generator, generated from gcc's opt files, to parse a subset of gcc options in gcc-options-parser ... now im looking for a cheap way to implement the "parse arguments from file" feature
challenge: string parsing → shlex in python
cheap solution: eval
#! /usr/bin/env bash
args=("$@")
argsLen=${#args[@]}
argsParsed=()
for (( i=0; i<$argsLen; i++ ))
do
a="${args[$i]}"
case "$a" in
@*)
argsFile="${a:1}"
[ ! -e "$argsFile" ] && { echo "error parsing option $a: no such file"; exit 1; }
eval fileArgs=( $(cat "$argsFile") ) # WARNING eval is unsafe
args=( "${args[@]:0:$i}" "${fileArgs[@]}" "${args[@]:$((i + 1))}" ) # replace the @file argument
argsLen=${#args[@]} # update length
: $((i--)) # re-parse the replaced argument
;;
*)
argsParsed+=("$a")
;;
esac
done
for (( i=0; i<${#argsParsed[@]}; i++ ))
do
echo "$i: ${argsParsed[$i]}"
done