I am trying to write a program which will let me cd into a directory. My program is called mangy, I also have a mangy.sh script and a mangy function defined in .bashrc
mangy.sh is as follows
out= $($HOME/.mangy/mangy $#)
if [ "$1" == "g" ] || [ "$1" == "go" ] ; then
cd "$out"
else
echo "$out"
fi
and here is my function in .bashrc
function mangy() {
source $HOME/.mangy/mangy.sh $#
}
export -f mangy
~/Desktop is an example of whatout would contain
When I run the mangy function it outputs /home/ryan/Desktop: Is a directory
but doesn't navigate me there. I swear I had this working at one point but can't remember how I did it
You are trying to source the parameter. Sourcing a script is different from executing it. Sourcing just includes the file, so this should do:
function mangy() {
source $HOME/.mangy/mangy.sh
}
Also, you should quote the $# if you don't want it to be split by spaces.
out=$($HOME/.mangy/mangy "$#")
Also, it may be simpler not to have mangy.sh at all, though it's really your decision. You can put it directly in .bashrc.
function mangy() {
out= $($HOME/.mangy/mangy $#)
if [ "$1" == "g" ] || [ "$1" == "go" ] ; then
cd "$out"
else
echo "$out"
fi
}
Related
I've written a couple functions in my .bashrc to make navigating easier in bash:
# makes 'cs' cd and ll
function cs () {
cd "$1" && ll
}
# makes 'cv' cd and vim
function cv () {
mkdir -p $(dirname "$1") &&
cd $(dirname "$1") &&
if [ $(basename "$1") == no ]
then
:
else
vim $(basename "$1")
fi
}
# makes cc a 'smart' cd
function cc () {
if [[ "$1" == */ ]]
then
cs "$1"
else
cv "$1"
fi
}
The first two work as expected: cs moves and lists and cv moves and opens in vim (or creates the path to file). cc also works, but when I try to use tab autocompletion with it, my shell freezes. Even a CTRL+C won't unfreeze it.
Any ideas about why it won't autocomplete?
Thanks.
Often, I find my self writing the following in BASH script,
if [ -f /very/long/path/tofile/name ]; then
do_someting /very/long/path/tofile/name
fi
For example:
if [ -f /usr/local/bin/virtualenvwrapper.sh ]; then
source /usr/local/bin/virtualenvwrapper.sh
fi
The obvious way to short-cut it would be:
WRAPPER=/usr/local/bin/virtualenvwrapper.sh
if [ -f ${WRAPPER} ]; then
source ${WRAPPER}
fi
But I am wondering if there is some kind of a built-in variable to spare me
the manual declaration?
You can with && operator:
test -f file && cat file
The command after && will run only if first command run successfully.
See: Run command2 only if command1 succeeded in cmd windows shell
If you want to write /very/long/path/tofile/name only once you can define a function and just run it.
function run_smart {
if [ -f "$2" ]; then
"$1" "$2"
fi
}
run_smart cat /very/long/path/tofile/name
I want to underline to my bash shell prompt(=PS1) only when a current directory is changed.
I tried this.
At .bashrc file I wrote
DIR_CHANGED=
function cd {
builtin cd "$#"
DIR_CHANGED=1
}
function dir_ul {
# if $DIR_CHANGED is 1, draw underline
if [ x == x$DIR_CHANGED ]; then echo -en '\033[0;34m'; else echo -en '\033[4;34m'; fi
export DIR_CHANGED=''
}
export PS1='$(dir_ul)\w$(tput sgr0)$ '
But not worked.
How do I fix?
I hate to say it, but I'd call that a bash bug. Here's a workaround: use PROMPT_COMMAND to
copy $DIR_CHANGED and reset it, and in dir_ul refer to that saved copy. Minimal changes:
function dir_ul {
if [ x == x$DIR2 ]; then echo -en '\033[0;34m'; else echo -en '\033[4;34m'; fi
}
PROMPT_COMMAND='DIR2=$DIR_CHANGED;DIR_CHANGED='
Test this in your ~/.bashrc with a second shell:
PREV="$PWD"
PROMPT_COMMAND='[[ $PREV != $PWD ]] && PS1="$(tput smul)\w$(tput rmul)$ " && PREV="$PWD" || PS1="$(tput rmul)\w$ "'
The $(dir_ul) gets evaluated at the instance you set the PS1 variable, rather than being continuously updated.
I wanted to create the alias for the a bash script that make use of wild card as an argument. When I am trying to make use of the alias cmd its not giving the required output.
The usage of the alias cmd will be log_list /tmp/abc*
#usage log_list /tmp/abc*
alias log_list=`sh scriptname $1`
#here is the script code
for file_name in $* ; do
if [ ! -d $file_name ] && [ -f $file_name ] ; then
#do some processing ...
echo $file_name
fi
done
Aliases don't handle arguments via $1 and the like; they just prepend their text directly to the rest of the command line.
Either use:
alias log_list='sh scriptname' # note that these are single-quotes, not backticks
...or a function:
log_list() { sh scriptname "$#"; }
...though if your script is named log_list, marked executable, and located somewhere in the PATH, that alias or function should be completely unnecessary.
Now, that said, your proposed implementation of log_list also has a bunch of bugs. A cleaned-up version might look more like...
#!/bin/sh
for file_name in "$#" ; do
if [ ! -d "$file_name" ] && [ -f "$file_name" ] ; then
#do some processing ...
printf '%s\n' "$file_name"
fi
done
Just like a local .bashrc file, which is sourced every time I entered the directory.
How to make this work?
You can use an alias:
$ echo 'echo "execute something for $PWD"' > tests/.cdrc
$ _cd()
{
\cd $1
[ -r .cdrc ] && . .cdrc
}
this function first change to the dir specified as argument, check if the file .cdrc is readable and source it.
$ alias cd=_cd
Then
$ cd tests
execute something for /path/to/tests
bash and zsh (and probably many other shells) have a feature that allows you to run an arbitrary command before the prompt is displayed. You can use this to source a .dirrc file, and it won't break tab completion.
Here's how to do it in bash:
PROMPT_COMMAND='
if [ "${PREV}" != "$(pwd -P)" ]; then
if [ -r .dirrc ]; then
. ./.dirrc
fi
PREV=$(pwd -P)
fi
'
From the bash man page:
PROMPT_COMMAND: If set, the value is executed as a command prior to issuing each primary prompt.
This is how to do it in zsh (see the zshmisc man page):
precmd() {
if [ "${PREV}" != "$(pwd -P)" ]; then
if [ -r .dirrc ]; then
. ./.dirrc
fi
PREV=$(pwd -P)
fi
}