You are not logged in.
Hi everyone,
i've been adding some useful functions and aliases i found at these forums to my .bashrc.
However, i have some problems with shell scripting i hope someone more knowledgable here can help me out with:
1)
I've found a useful function here at the forum that detaches an application from the terminal and redirects the output to /dev/null.
The problem is, sudo doesn't recognize it.
One example:
alias sm="nh sudo medit" works.
alias sm="sudo nh medit" gives me nh: command not found
Can i make sudo recognize functions in my .bashrc?
2)
I use the alias f="find | grep" which works very nice for me however it only searches the current working directory.
What i want to achieve is an alias or function that let's me specify the path "find" will look in so i can write: f path file.
Among others I've tried alias fs="{ find $1 -iname '*'$2'*'; }" and similar aliases and functions but either find or grep (if used) are always complaining about something.
3)
This is actually quite similar to 2).
I've added shopt -s extglob to my .bashrc which allows me to exclude files from removal via rm !(file).
So now i can type rm !(g*) and everything in the current directory except files starting with g get deleted.
This is great but since I'm very lazy i want to wrap it in an alias so i can type the following with wildcard support just like above:
rme file1 file2 file3
I hoped alias rme="rm !($1) ($2) ($3)" would do the trick here but i guess i suck at shell scripting.
Any suggestions?
Thanks for your help.
Regards,
demian
Last edited by demian (2010-04-13 09:35:45)
no place like /home
github
Offline
Ad 1.
alias sudo="sudo "
does the work. Mind the space.
Thinkpad T61p : T7700 | 4GB RAM | nVidia FX 570M | Intel 4965
Arch64 @ Openbox
Offline
I'm afraid that's not it. I already have that alias in my .bashrc.
no place like /home
github
Offline
for #2 and #3, you will want to put a function in your .bashrc rather than an alias.
Offline
I'm afraid that's not it. I already have that alias in my .bashrc.
Well, then that's another advantage of zsh
Thinkpad T61p : T7700 | 4GB RAM | nVidia FX 570M | Intel 4965
Arch64 @ Openbox
Offline
#1
Maybe you should put 'nh' in your $PATH or use the full path in your alias / function. What's the output of 'type nh'?
As Allan said: use functions.
Instead of:
alias fs="{ find $1 -iname '*'$2'*'; }"
use:
fs() { find $1 -iname '*'$2'*'; }
Or - as suggested by vi3dr0 - use zsh.
Last edited by karol (2010-04-11 14:29:03)
Offline
Regarding issue 1)
17:22 ~ > type nh
nh is a function
nh ()
{
nohup "$@" &>/dev/null &
}
Could you explicate what you mean by adding nh to the path? I have a PATH variable defined for my own scripts and i actually thought of adding .bashrc somehow to it, but i don't really know how. I guess i would have to export the function into a file and add that directory containing that file to my PATH=$PATH:..."?
If switching to zsh would fix issue 1 i'd consider it. But wouldn't i have to rewrite most of my .bashrc? Because that'd probably be alot of work.
Regarding issue 2)
Thanks, I'm using functions for finding files / content now and it works splendid.
f () { find -iname $1 2>/dev/null; }
fc ()
{ # find | grep
if [ $# -eq 0 ]; then
echo "findcontent: No arguments entered."; return 1
else
# "{.[a-zA-Z],}*" instead of "." makes the output cleaner
find {.[a-zA-Z],}* -type f 2>/dev/null | xargs grep --color=auto -n $* 2>/dev/null
fi
}
fcd ()
{ # find | grep
if [ $# -eq 0 ]; then
echo "findcontent: No arguments entered."; return 1
else
# "{.[a-zA-Z],}*" instead of "." makes the output cleaner
find $1 {.[a-zA-Z],}* -type f 2>/dev/null | xargs grep --color=auto -n $2 2>/dev/null
fi
}
fd () { find $1 -iname $2 2>/dev/null; }
ff () { find / -iname $1 2>/dev/null; }
Do you by chance know how i can get the find output colorized? I tried it with grep but i had some trouble with wildcards.
Other than that, issue 2 is solved now, thanks guys .
Regarding issue 3)
I couldn't make that work even with functions. I wonder if it's even possible using "shopt -s extglob".
Because if i run "rm !(g*)" in my terminal it works fine. Every file except those starting with g get deleted.
But if i fun "rm !(g*) !(7*)" to keep files starting with 7 too, everything get's deleted. Not even those starting with g remain.
I'd be glad for any input here.
Regards,
demian
Last edited by demian (2010-04-11 15:32:50)
no place like /home
github
Offline
#1: the problem is that functions and aliases defined in your .bashrc are not recognised by sudo, as you are technically running as root = no local bashrc files. Im not sure if there is a way to get sudo to read local bashrc files, but what you can do is write it as a separate bash file and put it somewhere in your PATH
#!/bin/bash
nohup "$@" &>/dev/null &
#2: can i suggest protecting your arguments with quotes, just incase you want to search for anything with a space in it
fs() { find "$1" -iname "*$2*"; }
to get you started here is a similar function using find to what you have, but then it lets you select one of the found files and open it
findopen() {
local PS3="select file: "
files=( $(find "$1" -iname "$2" | sort | tr ' ' '@') )
select file in "${files[@]//@/ }"; do
${3:-exo-open} "$file"
break
done
}
the optional third argument is the command called on the selected file, the default is xdg-open (it chooses the most appropriate program based on mime types) but you can change it to rm or echo etc. FYI I replaced spaces in the filenames with '@' using tr so that select would work.
#3: the problem is that !(g*) and !(7*) are evaluated separately, what you need is
rm !(g*|7*)
Offline
Thank you, quigybo, for the very comprehensive answer. Almost everything now works exactly like i wanted it to. I'll definately look into bash scripting some more in the near future including more complex functions like findopen() you posted.
But for now, here are the working, very simple functions. I've also added some functions for resizing pictures that i (half) wrote (half copied) if someone's interested in that.
One more thing though before i can mark this thread as solved:
Do you know how i can get the output of my functions f, fd and ff colorized?
f () { find -iname "$1" 2>/dev/null; }
fd () { find "$1" -iname "$2" 2>/dev/null; }
ff () { find / -iname $1 2>/dev/null; }
I guess grep -i --color=auto is the way to go, but I'm having trouble with wildcards. While find *ck.k* would show me every file with that exact sequence in it but grep seems to have a different syntax? for wildcards so i don't get any search results.
Thoughts?
Regards,
demian
Last edited by demian (2010-04-12 16:19:06)
no place like /home
github
Offline
grep uses regular expressions, it's always good to know regular expressions; I have found the grep manpage to be excellent as an introduction and reference to regex
aur S & M :: forum rules :: Community Ethos
Resources for Women, POC, LGBT*, and allies
Offline
An alternative to storing functions in a file is to say, not this:
sudo myfunction arg1 arg2 # doesn't work
but instead this:
sudo bash -ic "myfunction arg1 arg2" # this reads ~/.bashrc before executing the command string, so it works
Basically the same thing is going on as if you had created this file:
#!/bin/bash
myfunction "$@"
and called:
sudo path/to/that/file arg1 arg2
It might be easier in one-off cases, though.
Offline
Thanks, Profjim.
alias sm="sudo bash -ic nh medit" works, but it ignores any arguments behind "medit".
For instance sm /etc/rc.conf will open a blank page in medit.
I've tried a couple of variations but since i didn't get it to work like i want it to i'm falling back to the suggestion of outsourcing my nh function and using the PATH variable and an alias which is working fine.
I'll also look into regular expressions for using grep with find to get the output colorized.
Thanks everyone!
Oh, one final thing. Can someone tell me how the following function would look like as a shell script?
# Running programs
function r()
{
$* &>/dev/null &
disown %%
}
Edit: Oh and thanks fsckd for mentioning regular expressions. They're incredibly useful. I'm rewriting my find functions now to use grep only .
Last edited by demian (2010-04-13 12:38:02)
no place like /home
github
Offline
In general you dont need to make many changes to a function to make it a shell script, as they are both interpreted by bash anyway. So the contents of your r() function will run fine as they are in a shell script, but note that you dont need to disown the process from the script like you would from a shell, as this happens when the script ends anyway.
As another note I would probably use "$@" instead of $*, as I said before about protecting the expansion of variables in case you want to work with variables with spaces in them. Check the bash man page for the difference between $* and $@.
So for completeness here is your run function as a shell script
#!/bin/bash
"$@" &> /dev/null &
Offline
Thanks, Profjim.
alias sm="sudo bash -ic nh medit" works, but it ignores any arguments behind "medit".
For instance sm /etc/rc.conf will open a blank page in medit.
I've tried a couple of variations but since i didn't get it to work like i want it to i'm falling back to the suggestion of outsourcing my nh function and using the PATH variable and an alias which is working fine.
I think that's a good solution. With respect to the aliases though, I think bash's -c operator is looking for a single argument as a command: it doesn't just use the whole rest of the string. So your current alias is running something like this under sudo:
[bash] [-i] [-c nh] [medit]
which gives bash both a -c string and a script file (medit).
I think what you'd want instead would be an alias like:
alias sm="sudo bash -ic 'nh medit'"
Note the single quotes.
Offline
Yup, i thought about that too and tried it in different variations. Still couldn't get it to work though. sm /etc/rc.conf for instance opens a blank page in medit.
I admit I'm curious as to why it's not working but not enough to dig into the bash manpage .
Regards,
demian
Last edited by demian (2010-04-14 09:54:20)
no place like /home
github
Offline
Well, it recommends to avoid aliases for anything non-trivial anyway.
Offline
couldn't you use.... ?
sm() { sudo bash -ic "nh medit $@"; }
nh () { nohup "$@" &>/dev/null & }
Offline
Yeah... that actually works. I wonder what went wrong before. I basically used those exact lines except for $1 instead of $@.
Thanks!
I'll be sticking with a seperate script though as i use that function in quite a few aliases.
Last edited by demian (2010-04-14 15:39:46)
no place like /home
github
Offline
demian wrote:I'm afraid that's not it. I already have that alias in my .bashrc.
Well, then that's another advantage of zsh
If I were to solve that with zsh, how would i do it?
setopt NO_HUP?
Last edited by demian (2010-04-18 14:25:23)
no place like /home
github
Offline