How to use command line switches in expect? - expect

I want to know how to use switches at the command line in expect just like getopts in bash scripts.
Thanks in advance

See How to pass argument in expect through command line in shell script and http://www.tcl.tk/man/expect5.31/expect.1.html (Usage section).
Update: Expect is based on Tcl, and the usual method in Tcl to parse optional arguments from the command line as in getopts is the cmdline library package. This is part of tcllib, so you might need to install that if it's not already on your system.

Related

Execute command that results from execution of a script whose name is in a variable

When posting this question originally, I totally misworded it, obtaining another, reasonable but different question, which was correctly answered here.
The following is the correct version of the question I originally wanted to ask.
In one of my Bash scripts, there's a point where I have a variable SCRIPT which contains the /path/to/an/exe which, when executed, outputs a line to be executed.
What my script ultimately needs to do, is executing that line to be executed. Therefore the last line of the script is
$($SCRIPT)
so that $SCRIPT is expanded to /path/to/an/exe, and $(/path/to/an/exe) executes the executable and gives back the line to be executed, which is then executed.
However, running shellcheck on the script generates this error:
In setscreens.sh line 7:
$($SCRIPT)
^--------^ SC2091: Remove surrounding $() to avoid executing output.
For more information:
https://www.shellcheck.net/wiki/SC2091 -- Remove surrounding $() to avoid e...
Is there a way I can rewrite that $($SCRIPT) in a more appropriate way? eval does not seem to be of much help here.
If the script outputs a shell command line to execute, the correct way to do that is:
eval "$("$SCRIPT")"
$($SCRIPT) would only happen to work if the command can be completely evaluated using nothing but word splitting and pathname expansion, which is generally a rare situation. If the program instead outputs e.g. grep "Hello World" or cmd > file.txt then you will need eval or equivalent.
You can make it simple by setting the command to be executed as a positional argument in your shell and execute it from the command line
set -- "$SCRIPT"
and now run the result that is obtained by expansion of SCRIPT, by doing below on command-line.
"$#"
This works in case your output from SCRIPT contains multiple words e.g. custom flags that needs to be run. Since this is run in your current interactive shell, ensure the command to be run is not vulnerable to code injection. You could take one step of caution and run your command within a sub-shell, to not let your parent environment be affected by doing ( "$#" ; )
Or use shellcheck disable=SCnnnn to disable the warning and take the occasion to comment on the explicit intention, rather than evade the detection by cloaking behind an intermediate variable or arguments array.
#!/usr/bin/env bash
# shellcheck disable=SC2091 # Intentional execution of the output
"$("$SCRIPT")"
By disabling shellcheck with a comment, it clarifies the intent and tells the questionable code is not an error, but an informed implementation design choice.
you can do it in 2 steps
command_from_SCRIPT=$($SCRIPT)
$command_from_SCRIPT
and it's clean in shellcheck

CMake's execute_process and arbitrary shell scripts

CMake's execute_process command seems to only let you, well, execute a process - not an arbitrary line you could feed a command shell. The thing is, I want to use pipes, file descriptor redirection, etc. - and that does not seem to be possible. The alternative would be very painful for me (I think)...
What should I do?
PS - CMake 2.8 and 3.x answer(s) are interesting.
You can execute any shell script, using your shell's support for taking in a script within a string argument.
Example:
execute_process(
COMMAND bash "-c" "echo -n hello | sed 's/hello/world/;'"
OUTPUT_VARIABLE FOO
)
will result in FOO containing world.
Of course, you would need to escape quotes and backslashes with care. Also remember that running bash would only work on platforms which have bash - i.e. it won't work on Windows.
execute_process command seems to only let you, well, execute a process - not an arbitrary line you could feed a command shell.
Yes, exactly this is written in documentation for that command:
All arguments are passed VERBATIM to the child process. No intermediate shell is used, so shell operators such as > are treated as normal arguments.
I want to use pipes
Different COMMAND within same execute_process invocation are actually piped:
Runs the given sequence of one or more commands with the standard output of each process piped to the standard input of the next.
file descriptor redirection, etc. - and that does not seem to be possible.
For complex things just prepare separate shell script and run it using execute_process. You can pass variables from CMake to this script using its parameters, or with prelimiary configure_file.
I needed to pipe two commands one after the other and actually learned that each COMMAND of the execute_process is piped already. So at least that much is resolved by simply adding commands one after the other:
execute_process(
COMMAND echo "Hello"
COMMAND sed -e 's/H/h/'
OUTPUT_VARIABLE GREETINGS
OUTPUT_STRIP_TRAILING_WHITESPACE)
Now the variable GREETINGS is set to hello.
If you indeed need a lot of file redirection (as you stated), you probably want to write an external script and then execute that script from CMakeLists.txt. It's really difficult to get all the escaping right in CMake.
If you can simplify your scripts to one command generating a file, then another handling that file, etc. then you can always use the INPUT_FILE and OUTPUT_FILE options. Or pass a filename to your command for the input.
It's often much cleaner to handle one file at a time. Although I understand that some commands may need multiple sources and destinations.

emacs inf-ruby run ruby buffer with argument?

Im using inf-ruby mode in emacs, I really live it. But anyone know how to run a ruby script with arguments by inf-ruby? for instance, I need to pass argument arg0 and arg1 to test.rb
test.rb -arg0 -arg1
The short answer: instead of M-x run-ruby, call it with a prefix arg like so: C-u M-x run-ruby. This will allow you to edit the command line.
The long answer: don't. Instead re-structure your code so that you can test / call all the functionality without relying on parsing the command line arguments. Then do some simple tests from the command line whether your argument parsing works out okay.

How Linux Shell identifies the short and long options for a corresponding command to be same?

I am trying to write a shell script which takes command line arguments which will be parsed using "getopts" command in the script, I would like to make sure that in my script short and long options works same i,e -i and --isite works same, please help me in achieving it.
As per my understanding you are creating your own script which take options and perform accordingly.
To achieve short and long options for a command use or option.
e.g.
case $1 in
-l|--list)
statement ;;
esac
where $1 is your option.
here your statement will get executed for both option -l and --list.
Make sure you're using 'getopts', and not 'getopt' which is obsolete. Also this is only valid in Korn Shell, as far as I'm aware.
Then the script line
getopts "f:(file)l(long)"
will equate -f with --file, and -l with --long.
All this is documented in the man getopts manual page on your system.

Adding a shell script to be executed with the 'mrt/meteor create' command in terminal

How can I run a shell script that is executed when I enter the 'mrt create' command in the terminal?
Great question Johann!
Alright, so to turn a shell script into something as convenient as a terminal command, all you need to do is create an alias for that script in your terminal's rc file. Further instructions as to how you can do that can be found here.
So all you need to do is list out the commands you want automated in the shell script, including the meteor/mrt commands, and pass the directory/project name with the special variable "$1" passes the first argument after your command into your script.
Here's the script I am currently using, which implements the folder structure from Discover Meteor and adds coffeescript and stylus-mixins There are probably some redundancies in commands. Let me know if you see anything that can be cleaned!

Resources