concatenating aliases in linux shell - linux

I would like to concatenate aliases. So for example, if I have the following:
alias aliasone="cat"
alias aliastwo="/etc/passwd"
I would like to be able to type in the shell something like "aliasone+aliastwo" and then the following command will be executed:
cat /etc/passwd
Can this be done?
Thanks!

Aliases are only for command substitution. If you want to have shorthand for arguments, use shell variables.
file=/etc/passwd
cat "$file"

Simply remove the "alias" from the second line. That is:
alias aliasone="cat"
folder="/etc/passwd"
And then you can write:
aliasone $folder
The problem is that alias evaluate commands; but in the second alias there is no command. In the case of a parameter is better to use a variable. If you have a more particular situation (e.g. you are are inside a script) tell us so we can give a better solution.

I think you are trying to run several aliases at the same time, one after another.
I might be wrong, but if this is the case, the easy solution will be to use && in a new alias.
For example you have two existing ones:
alias cdtomydir='cd /home/mydir'
alias listfilesindir = 'll'
then you are able to combine the two above into a third alias by using &&:
alias cdtomydirandlistfiles = 'cdtomydir && listfilesindir'

you can do this: alias aliasone='cat /etc/passwd' then just type aliasone and that's it then if you're going to use cat looking elsewhere then type alias aliastwo='cat /etc/shadow' for example. Anyway just change path and that's it and make sure that aliases are different and keep on mind that words used for commands aren't reserved.

Step 1:
alias ccat='cat $1'
Step 2:
ccat /etc/passwd
Output>>
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin.............

Related

Using "read" to set variables

In bash from the CLI I can do:
$ ERR_TYPE=$"OVERLOAD"
$ echo $ERR_TYPE
OVERLOAD
$ read ${ERR_TYPE}_ERROR
1234
$ echo $OVERLOAD_ERROR
1234
This works great to set my variable name dynamically; in a script it doesn't work. I tried:
#!/bin/env bash
ERR_TYPE=("${ERR_TYPE[#]}" "OVERLOAD" "PANIC" "FATAL")
for i in "${ERR_TYPE[#]}"
do
sh -c $(echo ${i}_ERROR=$"1234")
done
echo $OVERLOAD_ERROR # output is blank
# I also tried these:
# ${i}_ERROR=$(echo ${i}_ERROR=$"1234") # command not found
# read ${i}_ERROR=$(echo ${i}_ERROR=$"1234") # it never terminates
How would I set a variable as I do from CLI, but in a script? thanks
When you use dynamic variables names instead of associative arrays, you really need to question your approach.
err_type=("OVERLOAD" "PANIC" "FATAL")
declare -A error
for type in "${err_type[#]}"; do
error[$type]=1234
done
Nevertheless, in bash you'd use declare:
declare "${i}_error=1234"
Your approach fails because you spawn a new shell, passing the command OVERLOAD_ERROR=1234, and then the shell exits. Your current shell is not affected at all.
Get out of the habit of using ALLCAPSVARNAMES. One day you'll write PATH=... and then wonder why your script is broken.
If the variable will hold a number, you can use let.
#!/bin/bash
ERR_TYPE=("OVERLOAD" "PANIC" "FATAL")
j=0
for i in "${ERR_TYPE[#]}"
do
let ${i}_ERROR=1000+j++
done
echo $OVERLOAD_ERROR
echo $PANIC_ERROR
echo $FATAL_ERROR
This outputs:
1000
1001
1002
I'd use eval.
I think this would be considered bad practice though (it had some thing to do with the fact that eval is "evil" because it allows bad input or something):
eval "${i}_ERROR=1234"

How I can make alias called when it's called by a variable

I added an alias:
$ alias anyalias="echo kallel"
If I execute:
$ anyalias
kallel
it executes the echo command without any problem.
Now, if I define a variable in this way:
$ var="anyalias"
and then execute with this way:
$ $var
-ash: anyalias: not found
Then I got a shell error.
How I can make $var running the command defined in the anyalias alias?
I m not looking to change the way of calling $var. But I m looking for a way of changing the definition of the alias or export it.
Instead of alias consider using function:
anyfunc() { echo "kallel"; }
v=anyfunc
$v
kallel
Safer is to store the call of function in an array (will store arguments also, if needed):
var=(anyfunc)
"${var[#]}"
kallel
That's because alias expansion is performed previous to parameter expansion:
Command-line Processing
As you can see, you can go through the process again with eval, which is not recommended.
Instead, you can use some alternatives as the one by #anubhava.
Example
$ alias anyalias="echo kallel"
$ var=anyalias
$ $var
bash: anyalias: command not found
$ eval $var
kallel
Again, use eval carefully. It's just to illustrate the expansion process.

Linux Bash Scripting: Declare var name from user or file input

Hi i would like to do the following.
./script.sh some.file.name.dat another.file.dat
Filename1=$(echo "$1"|cut -d '.' -f 1,2)
Filename2=$(echo "$2"|cut -d '.' -f 1,2)
tempfile_"$1"=$(mktemp)
tempfile_"$2"=$(mktemp)
I know this code isn't working. I need to create these temporary files and use them in a for loop later, in which i will do something with the input files and save the output in these temporary files for later usage. So basically i would like to create the variable names dependent on the name of my input files.
I googled a lot and didn't found any answers to my problem.
I would like to thank for your suggestions
I'll suggest an alternate solution to use instead of entering the variable naming hell you're proposing (Using the variables later will cause you the same problems later, the scale will just be magnified).
Use Associative arrays (like tempfile[$filename]) instead of tempfile_"$filename". That's what associative arrays are for:
declare -A tempfile
tempfile[$1]=$(mktemp)
tempfile[$2]=$(mktemp)
cat ${tempfile[$1]}
cat ${tempfile[$2]}
rm -f ${tempfile[$1]}
rm -f ${tempfile[$2]}
Note: Associative arrays require bash version 4.0.0 or newer.
If you dont have Bash version 4.0.0 or newer, see the following answers for great workarounds that dont use eval.
How to define hash tables in Bash?
Associative arrays in Shell scripts
You cannot do that since Bash just doesn't allow dots in the names of identifiers/variables. Both of your arguments $1 and $2 have dots (periods) in them and that cannot be used in variable names you're trying to create i.e. tempfile_$1
See this page for details.
Try this:
eval "tempfile_"$1"=$(mktemp)"
eval "tempfile_"$2"=$(mktemp)"
Use something like:
f1=`echo $1|tr '.' '_'`
declare "tempfile_$f1=$(mktemp)"
Check out How to define hash tables in bash?

How can I pass a variable onto a command's parameter in a bash script?

Example bash script demonstrating my problem:
#!/bin/bash
function exclude
{
BACKUP_EXCLUDES="$BACKUP_EXCLUDES --exclude=\"$1\""
}
exclude "/proc"
exclude "/dev"
exclude "/mnt"
exclude "/media"
exclude "/lost+found"
echo $BACKUP_EXCLUDES
Output:
--exclude="/proc" --exclude="/dev" --exclude="/mnt" --exclude="/media" --exclude="/lost+found"
Perfect! But when I try adding:
rsync -ruvz $BACKUP_EXCLUDES / /some/backup/path
$BACKUP_EXCLUDES is completely ignored with no errors or warnings... Why?
you need to use array:
#!/usr/bin/env bash
BACKUP_EXCLUDES=()
function exclude
{
while
(( $# ))
do
BACKUP_EXCLUDES+=(--exclude="$1")
shift
done
}
exclude /proc /dev /mnt /media
exclude "/lost+found"
rsync -ruvz "${BACKUP_EXCLUDES[#]}" / /some/backup/path
the bash explanation: please check #janos answer
the zsh explanation (if it was Zsh): when you used a string variable it was like you passed --exclude="\"/proc\" --exclude=\"/media\" ..." - so it was treated as long path with spaces - which never matched.
It doesn't work because the quotes are included in the individual --exclude parameters. That is, rsync will ignore "/proc" instead of /proc. Of course "/proc" (with quotes) doesn't exist.
If you stick an eval in front of the command it will work, like this:
eval rsync -ruvz $BACKUP_EXCLUDES / /some/backup/path
In this case the --exclude="/proc" (and all others) will be evaluated to --exclude=/proc, that's why it will work.
But I think you should use arrays as proposed by #mpapis, or --exclude-from=FILE as proposed by a comment. Both are much better and cleaner solutions.

How to set the following in .cshrc for aliasing

I have following alias in my .cshrc
alias fe-fat "source fat /prj/work"
alias fe-fat1 "source fat1 /prj/work"
I wanted to know if we can set some variable for fat/fat1 and club the above 2 aliases into a single alias somewhat like the below, so that whenever I type fe-<variable> in the Unix terminal the above alias should work
alias fe-<variable> "source <variable> /prj/work"
No, I don't think that's possible with alias.
What are you actually trying to achieve?
It'd be simple enough to write a bash script that launches other commands based on a parameter (so you'd type fe <variable> instead of fe-<variable>).
It's not really worth it with only 2 commands but you could also provide a custom auto-complete script: See Line completion with custom commands
Any particular reason you wouldn't just alias it to something that takes a parameter?
alias fe "source \!:1 /prj/work"
fe fat #=> source fat /prj/work
fe fat1 #=> source fat1 /prj/work

Resources