
Surely, many people did the same as in the picture, but here they only had an error like “file not found”. Let's fix this problem so that with such obvious typos, exactly what you wanted would happen. That is, when you write “ssh <dirname>”, the entry into the <dirname> directory occurred and vice versa, when you do “cd <hostname>” an entry occurs in ssh. Well, at the same time, we will do the same for vim, so as not to get up 2 times.
Scripts with #! / Bin / sh at the beginning called ssh / cd / vim
If we try to go naively and just write scripts called “ssh”, “cd” and “vim”, then we really cannot run vim or ssh because of endless recursion:
')
This approach will work for the vim and ssh commands, if you call the script somehow differently, so that we do not turn to ourselves, or if we write the full paths to vim and ssh (then it will be unportable, since in different systems these utilities can live in different directories).
However, for the cd command this will not work from the word “absolutely”, unfortunately, since cd is a built-in command in bash. That is, neither “cd localhost” nor “ssh <dirname>” will work.
Also, we always look only at the first argument ($ 1), and passing additional flags will not work. For example, you will not be able to execute the “ssh localhost uptime” command and instead we will simply go ssh to localhost.
Improved script
Let's try to solve at least a problem with the fact that we are not passing arguments to the team. To do this, there is a very funny "$ @" construction, which serves to transfer the list of arguments to the commands "as is", taking into account the screening. This is different from "$ *", which sticks all the arguments to one, and also differs from $ * (without quotes), which will turn the arguments with whitespace into different arguments.
So, an improved version of the script:
Now the “vim localhost uptime” command will work if you put this script in / bin / vim. But all other problems will remain, unfortunately. We solved the problem with cd inside the script by calling echo, but still wanted to get a better solution, so that the directory changed and we didn’t have to type the cd command ourselves.
Bash aliases
Personally, I know 2 ways to replace the built-in commands in bash: aliases and functions. However, the possibilities of aliases are severely limited and the arguments that are passed to the function are not available to them:
$ alias cd='echo ALL YOUR BASH ARE BELONG TO US; cd' $ cd <some_dir> ALL YOUR BASH ARE BELONG TO US <some_dir>$
The aliases in the bash work very simply and are not deployed inside other aliases. In this case, the above example is almost all that can be done with aliases in the bash.
Sshcdvim function
Since we have almost no choice, let's write a function. It will look like this:
function sshcdvim() { if [ -d "$1" ]; then cd "$@" elif [ -f "$1" ]; then vim "$@" else ssh "$@" fi }
This code should be placed in ".bashrc" and restarted bash. Now you can use the sshcdvim function, which itself will choose what to run.
However, if you want to call your function cd, vim or ssh, then again you will get endless recursion when you try to use it.
Concepts builtin and command in bash
So that the declared functions in bash do not affect the execution of scripts, there are 2 keywords in bash: builtin and command.
The builtin keyword in front of the command name indicates to the interpreter that it is not necessary to run a function or command, but to run the built-in command. In our case, this built-in command is cd.
The command keyword does the same as builtin, but is used for real commands. In our case, the real commands are vim and ssh, so they should be used.
The final version will look like this:
function ssh() { if [ -d "$1" ]; then builtin cd "$@" elif [ -f "$1" ]; then command vim "$@" else command ssh "$@" fi }
For vim and cd commands, you can swap checks, if necessary.
Using this magic bash, you can amaze colleagues and even show tricks on TV! I hope you enjoyed the article and it will be useful for your daily work.