I'm trying to set variables in Automator but apparently it's not working?
It only outputs the latest variable; "Var2". What am I doing wrong?
This is what I'm trying to do
Ask for text
Set value of variable: Var1
Ask for text
Set value of variable Var2
Get value of variable Var1
Get value of variable Var2
Run Shell script (as arguments):
for f in "$#"
do
echo "$1" "$2"
done
The following Automator workflow works for me with the following actions, and make note of the Options settings:
Ask for Text
Set Value of Variable
Variable: [Var1]
Ask for Text
Options
[√] Ignore this action's input
Set Value of Variable
Variable: [Var2]
Get Value of Variable
Variable: [Var1]
Options
[√] Ignore this action's input
Get Value of Variable
Variable: [Var2]
Run Shell Script
Shell: [/bin/bash] Pass input: [as arguments]
echo "$1" "$2"
In the Results pane of the Run Shell Script action it shows what was typed in both Ask for Text actions, which were of course set to the Set Value of Variable actions.
For example, I typed "This is Var1" and "This is Var2" respectively, and the Results pane of the Run Shell Script action showed:
This is Var1 This is Var2
Note in the image below that I did not check the [] Require an answer check box in the Ask for Text action's Options, however this was just for testing and I did add text in each instance. For the real thing, you may want to check that check box.
Also note that by checking the [√] Ignore this action's input check box in the given actions, there is a break between that action and the previous action as noted by no visible connection compared to the ones that are visibly connected.
Related
Can I disable fish shell showing the values being shown on the screen when I type echo e.g $FOO .
Current I see when I do $F <tab> I see my shell shows all the environment variables with F and then on the right said of my prompt it displays their values like (Variable: <value of the environment value)
The answer is "No". This is not configurable in fish.
Oh... Probably title is not really easy to interpret. So let's describe it a little bit:
In .bashrc file I set PS1 to get custom prompt. In this prompt I need to have some additional info, which I get from other specific function. This function takes some time to exec so it is not cool to wait 1 sec after push enter in console. But I have idea to cached returned value from this specific function.
I need to check cache flag in every prompt print so I cant use variable, I must use function in printing prompt, because sourceing .bashrc is only one times, but if I pass function to PS1 it will be execed every time.
prompt_fun(){
export CACHE_YES=1
export PROMPT_CACHE="Something"
echo "$PROMPT_CACHE"
#in real case here will be checking if cache is turned on.
#If yes, we use cached value from exported variable in first time.
#If no, we exec specific function and export values to env variables.
}
PS1="$(prompt_fun): "`
Of course, variable CACHE_YES and PROMPT_CACHE are not set in console, so I am unable to control caching be changing CACHE_YES. I know when cache should change so I can type in console to change CACHE_YES=0 but my script don't rechange it to CACHE_YES=1 after cache new values.
How to make that export in prompt_fun have global effect?
The short answer is, you can't. Since prompt_fun is called in a command substitution, any changes made to variables in that subshell disappear when the subshell exits.
Instead, you'll want to set the value of PS1 inside prompt_fun, then call prompt_fun from the value of PROMPT_COMMAND, as the value of that parameter is executed in the current shell context prior to each prompt being displayed.
prompt_fun () {
if [[ -z $CACHE ]]; then
# Set value of $CACHE
fi
PS1=something
PS1+=something_else
PS1+=$CACHE
PS1+=final_value
}
PROMPT_COMMAND='prompt_fun' # Yes, single quotes
I'm using qsub to submit pbs jobs. My job file requires 5 environment variables be defined: qsub -v A=foo,B=bar,C=cat,D=dog,E=qux jobfile.sh. Sometimes, I might forget to define one of the variables on the command line when I submit only later to find out my error.
So, is there a way to catch the condition that not all environment variables are defined when submitting with qsub? Or am I going to have to accept that I have to be very careful when submitting job files with many required environment variables?
Thank you,
Paul
The best you can do is to add a runtime check to the beginning of jobfile.sh that will cause it to exit if any expected variables are not set.
set -u
: $A $B $C $D $E
set +u
set -u tells the shell to exit if an attempt is made to expand an unset parameter. The : command does nothing, but its arguments do undergo the standard expansions first, so if any of the five are unset, the shell will exit. set +u then disables the unset-parameter check for the remainder of the shell.
qsub itself cannot examine the given job to determine what variables it might need.
I really like the brevity of #chepner's answer, but if you don't want to fiddle with toggling set -/+u, then you can use this shell parameter expansion in a similar manner:
: ${A?} ${B?} ${C?} ${D?} ${E?}
If any of the variables are not set, then you'll get an error like this and the script will quit immediately:
./jobfile.sh: line 3: A: parameter null or not set
Optionally, you may override the default error message with your own like this:
${A?Your message here}
From the manual:
${parameter:?word}
If parameter is null or unset, the expansion of word (or a message to that effect if word is not present) is written to the standard error and the shell, if it is not interactive, exits. Otherwise, the value of parameter is substituted.
Is it possible to pass an Automator variable into a shell script?
To complement #Ned Deily's answer:
(Written as of OS X 10.9.2, still current as of OSX 10.10)
It is often not necessary to create and use explicit variables in Automator (using the Set Value of Variable and Get Value of Variable actions).
The previous action's output is automatically passed to a Run Shell Script action.
By default, the data is passed via stdin, however.
If you want it passed as arguments ($1, $2, ... - also accessible as an array via $#) instead, select as arguments from the Pass input: list on the right, as illustrated here:
In this example, the selected Finder items are passed as POSIX-style paths to the shell script.
That said, having a shell script process the data via stdin (using read -r in a loop) works, too:
Drag & drop
Store path in filename variable
Prompt window for input value in next variable
get filename variable
Store prompt value in rename_to
$1 – rename_to value, $2 – filename value
I get the name of a variable from the script user as the first argument and I echo the value of said variable back to the console:
#!/bin/bash
variablename=$1
echo "The value of $variablename is: " ${!variablename}
This works great!
What I can't get to work is if I want to change that variable into the value of the second argument from the user. An example with a syntax error is:
#!/bin/bash
variablename=$1
echo "The value of $variablename is: " ${!variablename}
echo "I will now try to change the value into $2."
(!variablename}=$2
# The above line generates: {!variablename}=2: command not found
In other words: If it is possible, how do I get a variable name from the user and both read (already solved) and write to said variable?
I had a flash all of a sudden, minutes after asking for help, and I think I have a solution:
#!/bin/bash
variablename=$1
echo "The value of $variablename is: " ${!variablename}
echo "I will now try to change the value into $2."
eval "$variablename=$2"
echo "Success! $variablename now has the value ${!variablename}!"
It works. Is there a better way?
Your solution will work but the variable will only have that value within your script. It won't affect the "calling" application's variable.
When you run a script or program it spawns a new shell with a copy of the environment. This is by design so your script doesn't modify things like PATH.
If you want your script to be able to modify environment variables for the calling shell you need to either source scriptname or . scriptname. This is how .bashrc works.