Shell script: shorten or aliasing an address after a command - shell

I want to abbreviate or set an alias to a destination address every time I use while copying files. For example,
scp <myfile> my_destination
where my_destination could be hbaromega#192.168.1.100:Documents. So I want to modify my .bash_profile by inserting something like
alias my_destination = 'hbaromega#192.168.1.100:Documents' .
But that doesn't work since my_destination is not a command.
Is there a way out?
Note: I don't want to abbreviate the whole command, but only the address, so that I can use it with other possible commands.

You can't do what you want for the reason you state (an alias defines an entire command). But you could use a shell function to come close:
my_scp() {
scp "$#" hbaromega#192.168.1.100:Documents/.
}
which you could then call as
my_scp *.c
(Using $# in doublequotes is shell black magic that avoids trouble if any of the file names matched by the *.c glob contain spaces)
Of course, if you don't want to define a function, you could always use a shell variable to at least save the retyping:
dest='hbaromega#192.168.1.100:Documents/.'
scp *.c $dest

You have a couple options. You can set hostname aliases in your ~/.ssh/config like this:
Host my_destination
Hostname 192.168.1.100
User hbaromega
You could use it like this:
$ scp myfile my_destination:Documents/
Note that you'd still have to specify the default directory.
Another option would be to just put an environment variable in your ~/.bashrc:
export my_destination='hbaromega#192.168.1.100:Documents/'
Then you could use it like this:
$ scp myfile $my_destination
BertD's approach of defining a function would also work.

I think this works without using export as well since anyway I am assigning a variable for the path or destination. So I can just put the following in my .basrc or .bash_profile :
my_destination='hbaromega#192.168.1.100:Documents/'
Then
scp <myfile> $my_destination
Similarly I can execute any action (e.g. moving a file)for any local destination or directory:
local_dest='/Users/hbaromega/Documents/'
and then
mv <myfile> $local_dest
In summary, a destination address can be put as a variable, but not as a shell command or function.

The reason it does not work is there are spaces surrounding the = sign. As pointed out, an alias must be called as the first part of the command string. You are more likely to get the results you need by exporting my_destination and then calling it with a $. In ~/.bashrc:
export my_destination='hbaromega#192.168.1.100:Documents'
Then:
scp <myfile> $my_destination
Note: you will likely need to provide a full path to Documents in the export.

Related

Bash command line: Is there a way to use the first parameter's value as part of second parameter?

I frequently make temporary backups of files by making a file with nearly the same name, e.g.:
cp /some/long/path/code.php /some/long/path/code.phpcode.php.WIP_desc
Is there some way to shorten this without creating an alias?
You can use brace expansion in bash:
cp /some/long/path/code.php{,.WIP_desc}
Create a file named makeFileBackup with this content
#!/usr/bin/env bash
cp "$1" "$1.WIP_desc"
and then run chmod +x makeFileBackup.
Now you can use it as /path/to/makeFileBackup some_file.
As suggested in a command, you might want to use the above program without having to specify /path/to/ in front of it. Two general approaches are possible:
move makeFileBackup to, or create a link to it in a location that's already in PATH;
add to PATH the location where makeFileBackup is; in this case, you probably still don't want it to be in /home/yourusername but in its own directory.
Is creating a variable ok?
p=/some/long/path
cp $p/code.php $p/code.phpcode.php.WIP_desc
Double quote the expansion if p may contain white space.

Use content of file as part of a Bash command

I want to use the content of a file.txt as part of a bash command.
Suppose that the bash command with its options that I want to execute is:
my_command -a first value --b_long_version_option="second value" -c third_value
but the first 2 options (-a and --b_long_version_option ) are very verbose so instead of inserting directly on the command line (or bash script) I wrote them in a file.txt like this:
-a first value \
--b_long_version_option="second value"
Now I expect to call the command "my_command" with the following syntax (where "path_to/file.txt" is the path to file.txt, expressed in relative or absolute form):
my_command "$(cat path_to/file.txt)" -c third_value
This however is not the right syntax, as my command is breaking and complaining.
How should I write the new version of the command and/or the file.txt so that it is equivalent to its native bash usage?
Thanks in advance!
The quotes are preserving the newlines. Take them off.
You also don't need the cat unless you're running an old bash parser.
my_command $(<path_to/file.txt) -c third_value
You'll need to take the backslashes at the ends of lines out.
Be careful doing things like this, though. It's probably better to just put the whole command in the file, rather than just pieces of it. If you really just want arguments, maybe define them a little more carefully in an array, source the file and then apply them, like this:
in file:
myArgs=( "-a" "first value"
"--b_long_version_option=second value"
)
Note the quoting. Then run with
. file
my_command "${myArgs[#]" -c third_value
e.g.,
$: printf "[%s] " "${myArgs[#]}" -c=foo
[-a] [first value] [--b_long_version_option=second value] [-c=foo]
I haven't seen any example of what you're trying. But, there are simpler ways to achieve your goal.
Bash Alias
ll for example is a bash alias for ls -al. It usually is defined in .bash_profile or .bashrc as follows :
alias ll='ls -al'
So, what you can do is to set another alias for your shorthand command.
alias mycmd='mycommand -a first value --b_long_version_option="second value"'
then you can use it as follows :
mycmd -c third_value
Config file
You can also define a mycommand.json file or mycommand.ini file for default arguments. Then, you will need to check for config file in your software, and assign arguments from it.
Using config file is more advanced solution. You can define multiple config files. You can set default config file in /etc/mycommand/config.ini for example. When running on different directories, you should check ${cwd}/mycommand.ini to check local config file exists or not. You can even add a --config-file argument to your command.
Using alias is more convenient for small tasks, or thing that won't change much. If your command's behavior should be different in some other project, the using a config file would be a better solution.

Why does my PWD variable not retain its value?

I have the following code:
PWD="$(pwd)"
echo $PWD
cd
echo $PWD
If I run this from within /home/USER/sandbox, the output of the above is:
/home/USER/sandbox
/home/USER
Why does PWD not preserve its value? Is there any way to get it to preserve its value?
The key is that you called the variable PWD. This is one of several all-uppercase names used specially by Bash:
PWD
The current working directory as set by the cd command.
After each cd command, $PWD is updated to match.
I recommend you use lower-case for your variable names, to avoid surprises like this.
If I type all of those commands into the command line, I find that WD does "preserve it's value".
However I've run into this issue multiple times with various scripts and the root cause is one shell session (and/or a script) doesn't transfer its environment to another. Common solutions include doing everything I want to do in one script and saving values in a file for later use.
Hope this helps.

How to make a wget 'alias'?

I would like to make a command in the command prompt to easily download protein data base files by typing 'fetch ID.pdb'. The files are retrieved from www.pdb.org/pdb/files/ID.pdb.
I tried adding to .bash_profiles;
alias fetch ='wget www.pdb.org/pdb/files/'
I thought I could then type 'fetch ID.pdb' and it would work, but it seems aliases do not work that way. Any advice? If I could retrieve the protein by typing only 'fetch ID', even better!
Thank you.
Try using a function in your .bashrc rile
function fetch() {
wget www.pdb.org/pdb/files/${1}
}
The alias approach does not work because the shell simply replaces the alias with the command you have set the alias to. Thus in your question, the shell would produce: wget www.pdb.org/pdb/files/ ID.pdb. The space, would foil wget. Using a function lets you pass an argument that you can simply append to the URL.
The problem with your alias is that you need to remove the space between the word fetch and the = symbol. As EJK mentioned, there will be a space between your alias and the argument that you pass at the command line which will not create an appropriately formatted URL. Spaces are special characters in the shell.
Here's another solution that eliminates the need to add the .pdb file suffix to your file ID argument so that you can just enter:
fetch ID
Shell Script
Create a shell script called fetch.sh that includes the following:
#!/bin/bash
PDB_URL="http://www.pdb.org/pdb/files/"
if [ $# -eq 1 ]; then
PDB_FILE="$1"
wget "$PDB_URL$PDB_FILE.pdb"
else
echo "Forgot the file ID...Try again." >&2
exit 1
fi
Let's say you save that on the file path ~/scripts/fetch.sh. Run chmod on the shell script to make it executable:
chmod 744 ~/scripts/fetch.sh
Make an Alias for Your Shell Script
Enter the following alias in your .bashrc file:
alias fetch="~/scripts/fetch.sh"
Run a source command on the .bashrc file (with .bashrc in your working directory):
source .bashrc
And then pull your files with wget like this:
fetch 992532
using whatever ID you need. wget will place the file in whatever working directory you are in.
Hope it helps!

alias parameter not working

I am trying to make it easier to use scp so I learned about alias today, and I am using it like this:
alias loudie-scp="scp -i keys/aws.pem $1 ec2-user#ec2-107-20-68-112.compute-1.amazonaws.com:/home/ec2-user"
the $1 is there to specify the file i want to transfer over. However this is not working and giving me an error:
scp: /home/ec2-user: not a regular file
This does not happen when I execute this command manually passing in any file for $1.
BASH FAQ entry #80: "How can I make an alias that takes an argument?"
Unfortunately BASH aliases are kind of like find-and-replace -- they're not very powerful for the sort of task you describe. I would suggest using, instead, a script file and placing it in an executable directory; something like so:
#!/bin/bash
scp -i keys/aws.pem $1 ec2-user#ec2-107-20-68-112.compute-1.amazonaws.com:/home/ec2-user
Then, given that it has the name loudie-scp you could call it like so:
loudie-scp <parameter>
As I'm sure Ignacio's link will explain, an alias does nothing more than textually expand the alias to its value. It does not take arguments, you need to use a function for that.

Resources