This question already has answers here:
Make a Bash alias that takes a parameter?
(24 answers)
Closed 3 years ago.
Coding is one of my weaker areas and this is my first question on Stack Overflow.
What I want to is add a parameter in-between my command, and I'm thinking it can be done with an alias or function.
The command I am using is telnet and it is used to log into our switches.
The full command:
$ telnet switchname.compname.com
What I want to type:
$ enter 'switchname'
In turn, making the telnet command a simple enter and not having to consistently type .compname.com every time.
A simple function does nicely:
enter() { telnet $1.compname.com; }
Create a function to open the telnet session to the switchname given by the first argument (or to your default switchname if no argument is provided), e.g. in .bashrc you could do:
mytelnet() {
local swname=${1:-defaultname} ## use local vars within function
telnet $swname.compname.com ## connect to your switch
}
Then create the alias you want for enter, e.g.
alias enter='mytelnet'
Now at the command line you can type:
$ enter ## to go to defaultname.compname.com
or
$ enter switchname ## to go to switchname.compname.com
For testing you can just enter the function and alias on the command line, e.g.
$ mytelnet() { local swname=${1:-defaultname}; telnet $swname.compname.com; }
$ alias enter='mytelnet'
Then telnet away...
(note: you can simply name your function enter() and do away with the alias. I just find it convenient to define my functions at the top of my .bashrc and then create aliases, as needed, in the various sections below, but using an alias is by no means a requirement)
Try to use an alias in your rcfile, like ~/.bashrc, for example.
alias mytelnet='telnet the.desired.site'
Then source your rcfile like
source ~/.bashrc
or the equivalent
. ~/.bashrc
and type mytelnet to execute the command.
Or just use a bash variable, like
VAR="the.desired.site"
and execute telnet this way:
telnet $VAR
Also you can add a function to your rc file, like David C. Rankin mentioned.
function mytelnet () {
telnet <<< "$#"
}
export -f mytelnet
<<< "$#" will feed telnet in the same way, as if you are using any other command on the commandline with their additional parameters, like in bash $1, $2 and so on.
export -f marks the function mytelnet to be passed to child processes in your environment.
Related
I'm trying to chain two commands together in a function or alias.
What I want to do is ssh into a proxy box, and then into another box from there. So something like:
ssh -J mylogin#host mylogin#host2
So far i've tried:
function doot {ssh -J mylogin#host && mylogin#"$1"}
and:
function doot {ssh -J mylogin#host; mylogin#"$1"}
and:
alias doot="ssh -J mylogin#host; mylogin#"$1""
It either doesn't recognize the function, or the alias just gives me an error. I feel that it's having an issue with the "$1" but i'm not sure how to chain these two commands together.
I want to just type in doot [nameofhost] and execute the command
ssh -J mylogin#host mylogin#host2
Neither of your attempted functions or alias do ssh -J mylogin#host mylogin#host2. Why?
The use of && and ';' separate commands. In your case that would make two separate commands out of ssh -J mylogin#host and mylogin#"$1". You need a single command specifying mylogin#host as the jump-host and mylogin#"$1" as the final destination. Simply do:
doot() {
ssh -J mylogin#host mylogin#"$1"
}
(note: quotes are not wrong but not entirely needed as hostnames don't contain whitespace. Also note "$1" within the function refers to the function argument, not the command line argument for your script. You would need to call as doot "$1". There is no ';' or && involved.)
There is a problem with alias as an alias does not contain arguments. From man bash:
There is no mechanism for using arguments in the replacement text.
If arguments are needed, a shell function should be used (see FUNCTIONS below).
Also, you want to validate that $1 has been given. You can do that with:
[ -z "$1" ] && { ## validate at least one argument given
printf "error: destination hostname required as argument.\n" >&2
return 1
}
(note: if you are calling the function that includes this test from the command line in the parent shell, your function should return instead of exit. In that case exit would exit the parent shell. If you use the function within a separate script you call from the parent, then you want exit to close the subshell)
You did not specify if the proxy required any additional parameters, sssuming it just a jump box, allowing ssh
Function foo {
ssh mylogin#host ssh mylogin#host2
}
If your current user is ‘mylogin’, you can abbreviate to
ssh host ssh host2
I'm trying to write a simple script using bash which must take two variables: a name and a command; then apply these two variables inside a "alias" command like so: alias $1=$2.
It`s for an online school activity which teaches introduction to bash scripting.
What I have come up with is:
function doalias {
alias $1=$2
}
doalias $1 $2
Next thing I do is write inside the terminal ./doalias.sh inst "sudo apt-get install".
Now the message I get from the bash terminal is that "=" is not recognized as a command. Why is this and how can I solve it?
You need to put the passed parameter in quotes when actioning the alias command and so:
function doalias {
alias "$1=$2"
}
doalias "$1" "$2"
To have the alias set in the current shell, you will need to source the script and so:
source doalias.sh inst "sudo apt-get install"
I log into a lot of servers via ssh. Typically I just use the easy bash history search to scroll through my history of 'ssh' commands and find the one I want. However, eventually my .bash_history reaches its limit and I start losing entries, despite increasing the limits, etc..
I would rather just adjust my $PROMPT_COMMAND so that after every command, it checks to see if I ran a command with ssh, and if so, appends that command to a file somewhere.
I saw some relevant questions asked here and here but I am struggling to understand how to use these in a function that I can source from my .bashrc and add to my $PROMPT_COMMAND that will check if the last command entered started with ssh and copy it to a file.
For example, this does not work:
$ PROMPT_COMMAND="echo; foo; "
$ foo () { echo "command was: $BASH_COMMAND" ; }
$ ssh cn-0030
...(Ctrl-D)...
$ logout
Connection to cn-0030 closed.
command was: echo "command was: $BASH_COMMAND"
This also does not work:
$ foo () { echo !! | grep ssh --color ; }
Because !! gets expanded into the actual last command run immediately and then saved into foo, instead of being evaluated when foo is evaluated
This question already has answers here:
is it possible to use variables in remote ssh command?
(2 answers)
Closed 4 years ago.
in a bash script i try to do:
ssh -n $username#server2 "rm ${delete_file}"
but always get the error:
rm: missing operand
when I
> echo $delete_file
> /var/www/site/myfile.txt
I get the correct path.
What am i doing wrong?
Could it be that in your case, $delete_file is set on the remote host and not on your current machine?
If you want $delete_file to be expanded on the remote side (i.e., after ssh'ing into server2), you have to use single quotes:
ssh -n $username#server2 'rm ${delete_file}'
Other than that, do you set the value of delete_file in the same script (before ssh'ing), or before invoking your script? If latter is the case, it can't work: Variables are not propagated to scripts called by the current script/session.
You could do the following about it:
delete_file=<your-value> ./ssh-script
or:
delete_file=<your-value>
export delete_file
./ssh-script
As it turns out this last option was the problem, let me elaborate on best practices:
Better than setting environment variables would be the usage of positional parameters.
#!/bin/bash
# $1: file to delete
delete_file=${1:?Missing parameter: which file for deletion?}
ssh -n $username#server2 "rm ${delete_file}"
Usage of the script is now as simple as:
./ssh-script <your-file-for-deletion>
This way, you don't have to remember which variable is exactly expected by the script when calling it - simply call the script with a positional parameter.
As a bonus, the example uses parameter expansion to check for not-set or empty parameters:
delete_file=${1:?Missing parameter: which file for deletion?}
Whenever $1 happens to be unset or empty, the scripts exits immediately with exit code 1 and prints given message to stderr.
Question
How can one specify a user's emacs init file to load with emacsclient?
emacsclient does not understand '-u user' and '-a ALTERNATE-EDITOR' does not allow me to quote it and provide '-u user'.
For example, running:
/usr/bin/emacsclient -n -a '/usr/bin/emacs -u <username>' ~<username>/notes.txt
returns
/usr/bin/emacsclient: error executing alternate editor "/usr/bin/emacs -u <username>"
Background
I'm using emacs version 23.1.1 and emacsclient version 23.1.
emacs itself supports '-u user' to load a specified user's init file.
I use the following bash function in my aliases file to invoke emacs
# a wrapper is needed to sandwich multiple command line arguments in bash
# 2>/dev/null hides
# "emacsclient: can't find socket; have you started the server?"
emacs_wrapper () {
if [ 0 -eq $# ]
then
/usr/bin/emacsclient -n -a /usr/bin/emacs ~<username>/notes.txt 2>/dev/null &
else
/usr/bin/emacsclient -n -a /usr/bin/emacs $* 2>/dev/null &
fi
}
alias x='emacs_wrapper'
Typing x followed by a list of files:
Connects to an existing emacs server if one is running, otherwise starts a new one
Executes as a background process
Opens the list of files or my notes file if no files are provided
This works great when I'm logged in as myself. However, many production boxes require me to log in as a production user. I've separated my aliases into a bash script, therefore I can get my aliases and bash functions by simply running.
. ~<username>/alias.sh
Unfortunately, this won't let me use my .emacs file (~<username>/.emacs) :(
This problem has been driving me crazy.
If you can't include command line arguments in your alternate editor specification, then simply write a shell script which does that for you, and supply that as the alternate editor argument instead.
#!/bin/sh
emacs -u (username) "$#"
The point of the server/client model is that you have an existing Emacs with its own set of configurations, and then you connect via one or more clients.
What should the client do if the server was already configured to show the menu bar (a global setting), and the client says not to show it? What if another client attaches saying to show it?
If you want to use different settings for Emacs, use different emacs sessions.