Bash - how to process additional parameter in function? - bash

I have the following bash script but im unable to use my defined command "kctl" if i call it with "get pods". Do I maybe have to add a placeholder behind the command at the kctl() funtction or so?
#!/bin/bash
KCTL=$(which kubectl)
KUBECONFIG=$1
kctl() {
$KCTL --kubeconfig=$KUBECONFIG
}
kctl get pods
For some reason I always get back the kubectl help and not a list of pods at the default namespace.
Thanks in advance

Here ktcl is a function on its own, so it has its own parameters. When you use it in the end you pass additional parameters to it but then in the function you do nothing with them.
If your intention is to append the arguments to the command inside the function, you have to write it like this:
kctl() {
$KCTL --kubeconfig=$KUBECONFIG "$#"
}
Notice how the function doesn't see the arguments of the script, as they are shadowed by its own arguments.

Related

Define bash aliases to run git as specific user

Is it possible to define a function in a bash script which generically defines git-aliases for different users in order to let users apply their changes on a shared system so that the commits contains their username and email?
alias git_as_user1='GIT_AUTHOR_NAME="User1_pre User1_sur" GIT_AUTHOR_EMAIL="user1#company.de" GIT_SSH="/home/account/ssh_user_wrapper.sh" GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL git'
I came up with the following function, but it does not evaluate args at the time of the alias definition but later on, when the alias is called.
This is unintended and renders the approach useless.
function alias_git_as ()
{
alias git_as_$1='GIT_AUTHOR_NAME=$1 GIT_AUTHOR_EMAIL=$2
}
In .basrc:
alias_git_as "login" "Surname Prename" "user#company.de"
-> Won't work !!! -> Defines the alias git_as_login, but the second and third arg are dismissed. When a certain user runs git_as_login from his terminal he would need to pass "Surname Prename" "user#company.de" again. But the args should be captured at time the alias is defined.
Two issues:
You use single quotes, but those suppress expansion; to make expansion happen early, you need double quotes instead.
Your original code only takes two arguments, but your example usage uses three.
Also, to make this work with names with spaces, we use the bash 5.x feature ${var#Q} below.
# define the function
alias_git_as() { alias "git_as_$1=GIT_AUTHOR_NAME=${2#Q} GIT_AUTHOR_EMAIL=${3#Q}"; }
# use the function
alias_git_as "login" "Surname Prename" "user#company.de"
# use the invoked alias
git_as_login
See this working at https://ideone.com/PV09NG
A version that's compatible with older versions of bash while still retaining support for unusual author names may instead look like:
alias_git_as() {
local alias_def
printf -v alias_def 'git_as_%s=GIT_AUTHOR_NAME=%q GIT_AUTHOR_EMAIL=%q' "$1" "$2" "$3"
alias "$alias_def"
}

How do I pass a command parameter in a variable holding the command?

I want to produce the same output as this:
bash utilities.bash "is_net_connected"
But I don't know how to pass "is_net_connected" if command and file is stored in a variable like this:
T=$(bash utilities.bash)
I've tried these but it doesn't seem to work. It's not picking up ${1} in utilities.bash.
$(T) "is_net_connected"
$(T "is_net_connected")
Not the best way to inport but I'm trying to avoid cluttering my main script with function blocks.
T=$(bash utilities.bash) doesn't save the command; it runs the command and saves its output. You want to define a function instead.
T () {
bash utilities.bash "$#"
}
# Or on one line,
# T () { bash utilities.bash "$#"; }
Now
T "is_net_connected"
will run bash utilities.bash with whatever arguments were passed to T. In a case like this, an alias would work the same: alias T='bash utilities.bash'. However, any changes to what T should do will probably require switching from an alias to a function anyway, so you may as well use the function to start. (Plus, you would have to explicitly enable alias expansion in your script.)
You might be tempted to use
T="bash utilities.bash"
$T is_net_connected
Don't be. Unquoted parameter expansions are bad practice that only work in select situations, and you will get bitten eventually if you try to use them with more complicated commands. Use a function; that's why the language supports them.

Create shell alias with value from current path

I want to create a shell alias which would run
command ew --constantswitch --anotherconstantswitch <name>
Now the value name needs to be extracted from the current path. the current path looks like this
[username#path-to-shell-xxxxxxxx]/path/to/directory/with/name%
How can I create an alias such that when I run aliasX it will
Extract the name from current path (which is last value of the prompt)
Add this path to the command above and execute.
An alias may not be competent for the job, but a function surely do. Try this code:
myfunc() {
command ew --constantswitch --anotherconstantswitch "${PWD##*/}"
}
The trick is ${PWD##*/}. You know the automatic variable $PWD is exactly what you get when you run pwd, as well as Bash's builtin string substitution ${var##pattern} that removes pattern from the left of the variable with maximum match. So ${PWD##*/} removes everything except the name after the last slash, which as you described is what you're looking for.
In practice, a function is more versatile than an alias. If you still need to add extra arguments to the command, append "$#" to the end of the command inside the function, so any argument that you pass to the function will be forwarded to the command.
Since you're not trying to do anything involving arguments, an alias is actually possible:
alias aliasX='echo "${PWD##*/}"'
This will print the current directory name when you use aliasX. Or, using your example:
alias aliasX='command ew --constantswitch --anotherconstantswitch "${PWD##*/}"'
Notice that the alias must be in single quotes or $PWD will expand when you define it instead of when you use it.
For anything slightly more complex, you should use a function instead of an alias, as shown in iBug's answer.

Substitute a bash script variable twice

I would like to know if I can substitute a variable twice.
For example:
#global variable
TEST_SERV_EXT=""
#variables become from myconf.sh
TEST_SERV_EXT_FO='foo01'
TEST_SERV_EXT_BR='bar01'
I want dynamically construct those last two and assign them in TEST_SERV_EXT.
I tried something like this ${$TEST_SERV_COMP} but I'm getting "bad substitution" message.
I need something like php's feature "$$" or tcl's subst command.
Regards,
thandem
TEST_SERV_COMP=TEST_SERV_EXT_FO
TEST_SERV_EXT=${!TEST_SERV_COMP}
Look for indirect expansion in the bash manual.

Calling a function in a PHP script from the command line

I have a script that has a bunch of different parameterized functions. Is it possible to call any of these functions from the command line and pass in the arguments instead of me having to hard code the function calls in the script?
F.Y.I: I do know how to execute a simple PHP script from the command line
doesn't quite call the function, remember script.php has around 5 different functions and I am looking to call only 1, is that possible
No, you cannot do that directly. You have a few options:
Put every function in a separate php file and call the php file
use the first argument passed to the php file as the function name, and write a few lines of code to select the correct function.
Update:
Here is a example of using the first passed parameter as a function call:
if(function_exists( $argv[1] ))
call_user_func_array($argv[1], $argv);
php script.php arg1 arg2
access them as $argv[1], $argv[2]...and so on, in your script.
Not 100% sure what you're asking, but the execution would be something like
php script.php arg1 arg2 arg3
You seem to already know that. The method for accessing those arguments within the script itself would be to use the variable $argv, so $argv[0] would be the script, $argv[1] would be "arg1", etc. If that doesn't work, then use $_SERVER['argv'].
As for options, you can parse them with getopt
You could make the command-line script use its first argument as the function to call, and subsequently the arguments to pass to it. The arguments will appear in the magic array variable $argv.
// Zero'th "argument" is just the name of your PHP script
$name_of_php_script = array_unshift($argv);
// Next argument will be your callback
$callback = array_unshift($argv);
// Remaining arguments are your parameters
call_user_func_array($callback, $argv);
Obviously, you may want to make things more complicated for security, or to pass in special values of some sort, but this does the basic logic you describe in the question.
You can write an option, then pass the function to that eg myscript.php -function my_function
then in your script call the function like
$argv[1]()
getopt() takes CLI parameters.
php /path/to/myscript.php -a foo -b bar -c baz
$arguments = getopt("a:b:c:");
print_r($arguments);
Array
(
[a] => foo
[b] => bar
[c] => baz
)
Make it a function $arguments[a](); to call foo(); you can pass in b also if you have a function arg.

Resources