I am a new to terraform and struggling with using templatefile to pass a list to my script.yml.
I can pass the list devnames to a bash script without issues but I cannot figure it out with script.yml. With the belw configuration, when I run terraform plan, the list just shows as $devnames and does not unpack the content of the list devnames.
Can you please assist?
resource "aws_imagebuilder_component" "devmappings" {
name = "devmappings"
platform = "Linux"
data = templatefile("${path.module}/script.yml", {
device_names = join(" ", local.devnames)
})
version = "1.0.0"
}
I need to execute script.yml against the content of the list devnames
name: 'myName'
description: 'myDescrip'
schemaVersion: 1.0
phases:
- name: build
steps:
- name: Install-prereqs
action: ExecuteBash
inputs:
commands: ["echo $devnames; for i in `seq 0 26`; do; nvme_blkd='/dev/nvme$${i}n1'; if [ -e $nvme_blkd ]; then; mapdevs='$${devnames[i]}'; if [[ -z '$mapdevs' ]]; then; mapdevs='$${devnames[i]}'; fi; if [[ '$mapdevs' != /dev/* ]]; then; mapdevs='/dev/$${mapdevs}'; fi; if [ -e $mapdevs ]; then; echo 'path exists: $${mapdevs}'; else; ln -s $nvme_blkd $mapdevs; echo 'symlink created: $${nvme_blkd} to $${mapdevs}'; fi; fi; done"]
Related
I'm following this blog to setup a zsh function to switch aws cli profiles
: https://mads-hartmann.com/2017/04/27/multiple-aws-profiles.html
This is the zsh function in the blog:
function aws-switch() {
case ${1} in
"")
clear)
export AWS_PROFILE=""
;;
*)
export AWS_PROFILE="${1}"
;;
esac
}
#compdef aws-switch
#description Switch the AWS profile
_aws-switch() {
local -a aws_profiles
aws_profiles=$( \
grep '\[profile' ~/.aws/config \
| awk '{sub(/]/, "", $2); print $2}' \
| while read -r profile; do echo -n "$profile "; done \
)
_arguments \
':Aws profile:($(echo ${aws_profiles}) clear)'
}
_aws-switch "$#"
I added these lines to my ~/.zshrc, when I run source ~/.zshrc
It gives /.zshrc:4: parse error near `)'
I read the zsh function doc but still not very good at understanding the syntax and how could I fix this.
Have a look at the zsh man page (man zshmisc):
case word in [ [(] pattern [ | pattern ] ... ) list (;;|;&|;|) ] ... esac
As you see, you have to separate multiple pattern by |:
case $1 in
|clear)
....
I am trying to customize the Bira zsh-theme so that a clean branch is green and a dirty branch is red and has an asterisk at the end like so...
I have gotten it so that the color changes based on the branch's state, but cannot figure out how to get the asterisk to show up at the end. Below is what I have so far. I'm very new to customizing zsh-theme files, so any help would be much appreciated!
# ZSH Theme - Modified from bira.zsh-theme
local return_code="%(?..%{$fg[red]%}%? ↵%{$reset_color%})"
if [[ $UID -eq 0 ]]; then
local user_host='%{$terminfo[bold]$fg[red]%}%n#%m%{$reset_color%}'
local user_symbol='#'
else
local user_host='%{$terminfo[bold]$fg[cyan]%}%n#%m%{$reset_color%}'
local user_symbol='$'
fi
local current_dir='%{$terminfo[bold]$fg[yellow]%}%~%{$reset_color%}'
local git_branch='$(git_prompt_info)%{$reset_color%}'
function git_prompt_info() {
ref=$(git symbolic-ref HEAD 2> /dev/null) || return
echo "$(parse_git_dirty)$ZSH_THEME_GIT_PROMPT_PREFIX$(current_branch)$ZSH_THEME_GIT_PROMPT_SUFFIX"
}
PROMPT="
╭─${user_host} ${current_dir} ${git_branch}
╰─%B${user_symbol}%b "
RPS1="%B${return_code}%b"
ZSH_THEME_GIT_PROMPT_PREFIX="‹"
ZSH_THEME_GIT_PROMPT_SUFFIX="›$reset_color"
ZSH_THEME_GIT_PROMPT_DIRTY="$fg[red]"
ZSH_THEME_GIT_PROMPT_CLEAN="$fg[green]"
The parse_git_dirty function is defined in lib/git.zsh
By copying that function into your file and modifying it slightly, we can achieve what you want:
function git_prompt_info() {
ref=$(git symbolic-ref HEAD 2> /dev/null) || return
# Checks if working tree is dirty
local STATUS=''
local FLAGS
FLAGS=('--porcelain')
if [[ "$(command git config --get oh-my-zsh.hide-dirty)" != "1" ]]; then
if [[ $POST_1_7_2_GIT -gt 0 ]]; then
FLAGS+='--ignore-submodules=dirty'
fi
if [[ "$DISABLE_UNTRACKED_FILES_DIRTY" == "true" ]]; then
FLAGS+='--untracked-files=no'
fi
STATUS=$(command git status ${FLAGS} 2> /dev/null | tail -n1)
fi
if [[ -n $STATUS ]]; then
GIT_PROMPT_COLOR="$ZSH_THEME_GIT_PROMPT_DIRTY"
GIT_DIRTY_STAR="*"
else
GIT_PROMPT_COLOR="$ZSH_THEME_GIT_PROMPT_CLEAN"
unset GIT_DIRTY_STAR
fi
echo "$GIT_PROMPT_COLOR$ZSH_THEME_GIT_PROMPT_PREFIX$(current_branch)$GIT_DIRTY_STAR$ZSH_THEME_GIT_PROMPT_SUFFIX"
}
The only difference from the library function is assigning GIT_PROMPT_COLOR and GIT_DIRTY_STAR instead of echoing, and then using these in the final echo.
I want to run the script with different parameters if the wc of the text file is matched or not matched!
My Script:
#!/bin/sh
x= echo `wc -l "/scc/ftp/mrdr_rpt/yet_to_load.txt"`
if [ $x -gt 0 ]
then
sh /scc/ftp/mrdr_rpt/eam.ksh /scc/ftp/mrdr_rpt/vinu_mrdr_rpt.txt /scc/ftp/mrdr_rpt/yet_to_load.txt from#from.com to.name#to.com
elif
sh /scc/ftp/mrdr_rpt/eam.ksh /scc/ftp/mrdr_rpt/vinu_mrdr_rpt.txt /scc/ftp/mrdr_rpt/yet_to_load.txt from#from.com to.name#to.com, hi.name#hi.com
fi
You need to capture the output of wc accurately, and you need to avoid getting a file name in its output. You have:
x= echo `wc -l "/scc/ftp/mrdr_rpt/yet_to_load.txt"`
if [ $x -gt 0 ]
The space after the = is wrong. The echo is not wanted. You should use input redirection with wc. (wc is a little peculiar. If you give it a file name to process, it includes the file name in the output; if you have it process standard input, it doesn't include a file name in the output.) You should use $(…) in preference to back-quotes.
x=$(wc -l < "/scc/ftp/mrdr_rpt/yet_to_load.txt")
if [ $x -gt 0 ]
If you want to check if the file is not empty (rather than being a file with data but no newlines), then you can use a more direct test:
if [ -s "/scc/ftp/mrdr_rpt/yet_to_load.txt" ]
You should probably be using a name such as
DIR="/scc/ftp/mrdr_rpt"
and then referencing it to reduce the ugly repetitions in your code:
if [ $x -gt 0 ]
then
sh "$DIR/eam.ksh" "$DIR/vinu_mrdr_rpt.txt" "$DIR/yet_to_load.txt" \
from#from.com to.name#to.com
else
sh "$DIR/eam.ksh" "$DIR/vinu_mrdr_rpt.txt" "$DIR/yet_to_load.txt" \
from#from.com to.name#to.com, hi.name#hi.com
fi
However, I think the comma in the second line is probably not needed, and it might be better to use:
who="from#from.com to.name#to.com"
if [ -s "$DIR/yet_to_load.txt" ]
then who="$who hi.name#hi.com"
fi
sh "$DIR/eam.ksh" "$DIR/vinu_mrdr_rpt.txt" "$DIR/yet_to_load.txt" $who
Then you've only one line with all the names in it. And you might do even better with an array instead of string:
who=("from#from.com" "to.name#to.com")
if [ -s "$DIR/yet_to_load.txt" ]
then who+=("$who hi.name#hi.com" "Firstname Lastname <someone#example.com>")
fi
sh "$DIR/eam.ksh" "$DIR/vinu_mrdr_rpt.txt" "$DIR/yet_to_load.txt" "${who[#]}"
Using arrays means you can handle blanks in the names correctly where a simple string doesn't.
I just started writing shell scripts in Unix so, I am a total newbie
I want to read the arguments given when the user run the script
ex:
sh script -a abc
I want to read for argument -a user gave abc.
My code so far:
if ( $1 = "-a" )
then var=$2
fi
echo $var
I get an error.
Bash uses an external program called test to perform boolean tests, but that program is used mostly via its alias [.
if ( $1 = "-a" )
should become
if [ $1 = "-a" ]
if you use [ or
if test $1 = "-a"
#!/bin/sh
if [ $1 = "-a" ]; then
var=$2
fi
echo $var
You shoud be careful of the space between if and [
I want to be able to tell if a command exists on any POSIX system from a shell script.
On Linux, I can do the following:
if which <command>; then
...snip...
fi
However, Solaris and MacOS which do not give an exit failure code when the command does not exist, they just print an error message to STDOUT.
Also, I recently discovered that the which command itself is not POSIX (see http://pubs.opengroup.org/onlinepubs/9699919799/idx/utilities.html)
Any ideas?
command -v is a POSIX specified command that does what which does.
It is defined to to return >0 when the command is not found or an error occurs.
You could read the stdout/stderr of "which" into a variable or an array (using backticks) rather than checking for an exit code.
If the system does not have a "which" or "where" command, you could also grab the contents of the $PATH variable, then loop over all the directories and search for the given executable. That's essentially what which does (although it might use some caching/optimization of $PATH results).
One which utility is available as shell script in the Git repository of debianutils package of Debian Linux. The script seems to be POSIX compatible and you could use it, if you take into account copyright and license. Note that there have been some controversy whether or not and how the which utility should be deprecated; (at time of writing) current version in Git shows deprecation message whereas an earlier version added later removed -s option to enable silent operation.
command -v as such is problematic as it may output a shell function name, an alias definition, a keyword, a builtin or a non-executable file path. On the other hand some path(s) output by which would not be executed by shell if you run the respective argument as such or as an argument for command. As an alternative for using the which script, a POSIX shell function using command -v could be something like
#!/bin/sh
# Argument $1 should be the basename of the command to be searched for.
# Outputs the absolute path of the command with that name found first in
# a directory listed in PATH environment variable, if the name is not
# shadowed by a special built-in utility, a regular built-in utility not
# associated with a PATH search, or a shell reserved word; otherwise
# outputs nothing and returns 1. If this function prints something for
# an argument, it is the path of the same executable as what 'command'
# would execute for the same argument.
executable() {
if cmd=$(unset -f -- "$1"; command -v -- "$1") \
&& [ -z "${cmd##/*}" ] && [ -x "$cmd" ]; then
printf '%s\n' "$cmd"
else
return 1
fi
}
Disclaimer: Note that the script using command -v above does not find an executable whose name equals a name of a special built-in utility, a regular built-in utility not associated with a PATH search, or a shell reserved word. It might not find an executable either in case if there is non-executable file and executable file available in PATH search.
A function_command_exists for checking if a command exists:
#!/bin/sh
set -eu
function_command_exists() {
local command="$1"
local IFS=":" # paths are delimited with a colon in $PATH
# iterate over dir paths having executables
for search_dir in $PATH
do
# seek only in dir (excluding subdirs) for a file with an exact (case sensitive) name
found_path="$(find "$search_dir" -maxdepth 1 -name "$command" -type f 2>/dev/null)"
# (positive) if a path to a command was found and it was executable
test -n "$found_path" && \
test -x "$found_path" && \
return 0
done
# (negative) if a path to an executable of a command was not found
return 1
}
# example usage
echo "example 1";
command="ls"
if function_command_exists "$command"; then
echo "Command: "\'$command\'" exists"
else
echo "Command: "\'$command\'" does not exist"
fi
command="notpresent"
if function_command_exists "$command"; then
echo "Command: "\'$command\'" exists"
else
echo "Command: "\'$command\'" does not exist"
fi
echo "example 2";
command="ls"
function_command_exists "$command" && echo "Command: "\'$command\'" exists"
command="notpresent"
function_command_exists "$command" && echo "Command: "\'$command\'" does not exist"
echo "End of the script"
output:
example 1
Command: 'ls' exists
Command: 'notpresent' does not exist
example 2
Command: 'ls' exists
End of the script
Note that even the set -eu that turns -e option for the script was used the script was executed to the last line "End of the script"
There is no Command: 'notpresent' does not exist in the example 2 because of the && operator so the execution of echo "Command: "\'$command\'" does not exist" is skipped but the execution of the script continues till the end.
Note that the function_command_exists does not check if you have a right to execute the command. This needs to be done separately.
Solution with command -v <command-to-check>
#!/bin/sh
set -eu;
# check if a command exists (Yes)
command -v echo > /dev/null && status="$?" || status="$?"
if [ "${status}" = 127 ]; then
echo "<handle not found 1>"
fi
# check if a command exists (No)
command -v command-that-does-not-exists > /dev/null && status="$?" || status="$?"
if [ "${status}" = 127 ]; then
echo "<handle not found 2>"
fi
produces:
<handle not found 2>
because echo was found at the first example.
Solution with running a command and handling errors including command not found.
#!/bin/sh
set -eu;
# check if a command exists (No)
command -v command-that-does-not-exist > /dev/null && status="$?" || status="$?"
if [ "${status}" = 127 ]; then
echo "<handle not found 2>"
fi
# run command and handle errors (no problem expected, echo exist)
echo "three" && status="$?" || status="$?"
if [ "${status}" = 127 ]; then
echo "<handle not found 3>"
elif [ "${status}" -ne 0 ]; then
echo "<handle other error 3>"
fi
# run command and handle errors (<handle not found 4> expected)
command-that-does-not-exist && status="$?" || status="$?"
if [ "${status}" = 127 ]; then
echo "<handle not found 4>"
elif [ "${status}" -ne 0 ]; then
echo "<handle other error 4>"
fi
# run command and handle errors (command exists but <handle other error 5> expected)
ls non-existing-path && status="$?" || status="$?"
if [ "${status}" = 127 ]; then
echo "<handle not found 5>"
elif [ "${status}" -ne 0 ]; then
echo "<handle other error 5>"
fi
produces:
<handle not found 2>
three
./function_command_exists.sh: 34: ./function_command_exists.sh: command-that-does-not-exist: not found
<handle not found 4>
ls: cannot access 'non-existing-path': No such file or directory
<handle other error 5>
The following works in both bash and zsh and avoids both functions and aliases.
It returns 1 if the binary is not found.
bin_path () {
if [[ -n ${ZSH_VERSION:-} ]]; then
builtin whence -cp "$1" 2> /dev/null
else
builtin type -P "$1"
fi
}