using getopts to have 1 option require 4 options - bash

I have been trying to read a lot about getops for bash because I have a project that requires the use of it for a script. The issue is I cannot find what I want to call nested options (if its even called that) For the project I am required to have say 3 options that are optional. But if the user choses say option -i they are required to have options -f -l -e -n how would I be able to implement that?

Related

How to answer a bash arrow selection menu through script

little stuck atm with figuring out how to script an answer to a bash arrow selection menu
Basically my question is how do I script selection of an item based on name?
I do know that I can use the following command to select an option by index and this is as close as I've gotten but I think there's a way to select it by name instead
echo 5 | zapier link
Important notes:
When a version is already selected it gets the [currently linked app] at the end of the version, this needs to be taken into account in text search
The numbers in () i.e (142900) is important
Pretend the name that's blocked out in red is testOver
I would prefer not to have to install any tools to accomplish this, only use whats built into bash unless there's no other option.
Thanks in advance for your help!
To select a menu entry by search, you have to read zapier's output. Usally this would be a job for expect, but since you don't want to install anything, try the following:
mkfifo fifo
zapier link <fifo |
awk '/Which integration/ {m=NR}
m && /\(142900\)/ {print NR-m; fflush(); m=0}' >fifo
rm fifo
This selects the option containing the string (142900). Of course you can adapt the regex to select any other option. Also consider replacing /Which integration/ by the full title of the menu to make detection safer.
If you want to see the output of zapier, use | tee >(awk ... >fifo).
In case zapier behaves differently when running inside a pipe, run it inside a pseudo-terminal. If zapier buffers its output for pipes, using script or stdbuf to unbuffer the output is an absolute requirement. Otherwise the entire command may run into a deadlock.
script -qec './zapier link' /dev/null <fifo # on Linux
script -qe /dev/null ./zapier link <fifo # on BSD/macOS.
Unfortunately, awk does not know when the menu is fully printed, so it cannot look at all the options first and then decide afterwards, but has to select one option as soon as it sees it. If there is no such option, the script gets stuck. To solve this you could replace awk with a small bash script:
zapier link <fifo | while IFS= read -r ln; do
[[ "$ln" = *"Which integration"* ]] || continue
IFS=$'\n' read -rd '' -t1 -a opts
# insert code to pick an option from the array `opts`
# either `echo "$((i+1))"` to select option `${opts[i]}`
# or `break` to select no option
done >fifo

Override bash completion for every command

I have a (possibly ill-advised) idea for improving tab completion based on the command history. Ideally, I'd want to apply this to every command in the terminal.
Basically I'm looking for something like:
complete -F _my_function *
where the glob actually works.
Is this at all possible, or would I have to set it manually for every command I use?
complete -D defines the "default" completion procedure, for all commands for which no specific completion has been set. If you want the default to apply to all commands, just don't set any specific completions. If you want to remove a completion, use complete -r command (or complete -r to erase all of them).
Also see complete -E.
For details, see the Bash manual.

Bash completion for command line arguments and options

I'm writing a CLI for my app in go and I would like to provide users with bash completions for options and arguments.
The API is the following myapp [-f file] argument andI would like to provide completion for both the option -f and the argument.
I wonder how I can distinguish between the following two scenarios:
myapp -f some_path<tab><tab>
myapp -f some_file <tab><tab>
In the first case the user is still typing the option and he/she would like to see candidates for the file option. In the second he/she finished typing and would like to see the candidates for the argument.
The problem is that in both cases the value of os.Args is identical and I can't distinguish between the two scenarios. Is there a way to access the invocation string?
One solution would be to use a separator like -- between the option and the argument but I would like to know if there is a cleaner solution before I go down this path.

What is the difference between -p and -q options

We have decided to split our jmeter properties into 2 files. One contains more "environment" related variables and the other contains more application centric (stuffs that changes with version).
Everything seems to work fine when using "jmeter.sh -q file1 -q file2 -t test.jmx". However we found there was also a -p option. In which context should it be use (vs the -q?)
According to the documentation:
-p, --propfile {argument}
the jmeter property file to use
-q, --addprop {argument}
additional property file(s)
this is, using -p you overwrite jmeter.properties, using -q adds a custom properties file.

bash script: How to implement your own history mechanism?

I'm implementing an interactive bash script similar to the MySQL client, /usr/bin/mysql. In this script I need to issue various types of 'commands'. I also need to provide a history mechanism whereby the user can use the up/down arrow keys to scroll through the commands entered so far.
The snippet listed here (Example 15-6, Detecting the arrow keys) does not exactly do what I want it to. I really want the following:
The up/down arrow keys should operate in silent mode. Meaning, they should not echo their character codes on the terminal.
The other keys however (which will be used to read the command names and their arguments) must not operate in silent mode.
The problem with read -s -n3 is that it does not satisfy my simultaneously conflicting requirements of silent mode and echo mode, based solely on the character code. Also, the value -n3 will work for arrow keys but, for other/regular keys, it won't 'return control' to the calling program until 3 characters have been consumed.
Now, I could try -n1 and manually assemble the input, one character at a time (yuck!). But the character-code based silent-/echo-mode switching problem would still persist!
Has anyone attempted this thing in bash? (Note: I cannot use C, nor other scripting languages like Perl, Python, etc.)
EDIT
Continuing with Dennis' answer... You will also need to manually add your desired entries to your history via history -s, like so...
while read -e x; do
history -s "$x"
# ...
done
You can use read -e to have read use readline. It will process your cursor keys and maintain the history for you. You will also need to manually add your desired entries to your history via history -s, like so:
while read -e x; do
history -s "$x"
# ...
done
MySQL and Bash use the Readline library to implement this. Maybe you could use something like rlwrap or rlfe?
rlwrap has a special "one-shot" mode to act as a replacement for the 'read' shell command. If you wish, every occurrence of this command in your script can be given its own history and completion word list.
Use it like this:
REPLY=$(rlwrap -o cat)
or, specifying a history file and a completion wordlist:
REPLY=$(rlwrap -H my_history -f my_completions -o cat)

Resources