How to pbpaste in .bash_profile alias? - macos

I try to make a small alias script to automatically reset my OS X Fuse connection.
If I run this command in my terminal:
pgrep sshfs|pbcopy; kill -9 $(pbpaste);echo my_password|pbcopy; sudo
umount path/to/my/mount/folder;
it works perfectly. If I however add it to my .bash_profile as an alias:
alias mount-reset="pgrep sshfs|pbcopy; kill -9 $(pbpaste);echo my_password|pbcopy; sudo umount path/to/my/mount/folder;"
It jumps over the pbpaste command and echoes my_password. I always thought that the alias commands are executed exactly as if I would write them to the terminal, but why is this not working? How do I pbpaste in alias script? What fundamentals have I understood wrong?

You need to wrap the alias in single-quotes, rather than double-quotes. The relevant difference is that bash expands $something (including $(command)) inside double-quotes before executing the command. The way you have it at the moment, pbpaste is executed when .bash_profile runs, and whatever happens to be in the paste buffer at that time gets included in the alias. With single-quotes, it includes $(pbpaste) directly in the alias, so it gets expanded when you use the alias.
alias mount-reset='pgrep sshfs|pbcopy; kill -9 $(pbpaste);echo my_password|pbcopy; sudo umount path/to/my/mount/folder;'
However, there's an easier way. I don't see any reason to pass the sshfs PID through the paste buffer; just use include it directly:
alias mount-reset='kill -9 $(pgrep sshfs);echo my_password|pbcopy; sudo umount path/to/my/mount/folder;'
...but that's still more complicated than it needs to be, because OS X includes a killall command which kills processes by name, thus eliminating the need to pgrep:
alias mount-reset='killall -9 sshfs;echo my_password|pbcopy; sudo umount path/to/my/mount/folder;'
(BTW, some unixes include a command named killall that does something much more dangerous -- this alias is not portable!)

In OS X alias commands should be added to ~/.bashrc
When bash is an interactive non-login shell it uses .bashrc, not .bash_profile. If bash is invoked as an interactive login shell, it uses .bash_profile, not .bashrc.
Try adding the alias to ~/.bashrc. If you wanted to add a mount-reset command as an interactive login shell command into ~/.bash_profile you could use something like this:
# kill sshfs
mount-reset () { pgrep sshfs|pbcopy; kill -9 $(pbpaste); echo my_password|pbcopy;
sudo umount path/to/my/mount/folder; }

Related

Shell Script that does chroot and execute commands in chroot

If in shell script I write
chroot /home/mayank/chroot/codebase
cd SBC
when I run this shell script It does go in the chroot but does not execute the command cd SBC,
when I exit chroot then it executes cd SBC.
How can I achieve something that does chroot and execute commands in chroot through shell script ??
When you run chroot without telling it what to do, it will try to start chrooted interactive shell session. So your script would "pause" at that point and when you are done with that interactive shell session, it continues out of chroot again.
One of the quick and dirt options would be to abuse here-document, like this:
chroot /home/mayank/chroot/codebase /bin/bash <<"EOT"
cd /tmp/so
ls -l
echo $$
EOT
Which takes all lines up to EOT and feeds them into bash started through chroot. Those double quotes around "EOT" should ensure bash passes the content not trying to expand variables and such. Hence that echo $$ should be PID of the inner chrooted bash.
somewhat I found a solution,
chroot /work3/tmp_GU/$build_env/sbcbuild/chroot ./test.sh
after chroot giving a script there is working fine for me.
test.sh present in the chroot folder.
All commands in test.sh will be executed in chroot folder.
So basically giving a command after chroot
man chroot
chroot [OPTION] NEWROOT [COMMAND [ARG]...]

Sending Bash Aliases to detached screen sessions

I'm on a Linux machine using screen, and I'm attempting to write a (fairly portable) function which runs a bash function in a new, detached screen session which automatically closes upon completion. I've had some success, but I noticed the following behavior:
If I include the definition of mail_submit() in my ~/.bashrc file, I can run
mail_submit foo
in the terminal, and also I can access the alias in a new screen session:
screen -S test
mail_submit foo
However, the following command does not work:
screen -d -m -S test sh -c 'mail_submit foo'
presumably because sh -c starts a fresh shell that has no knowledge of my ~/.bashrc profile. So, I can use the following fix:
screen -d -m -S test sh -c 'source ~/.bashrc; mail_submit foo'
which does work.
But if I want to wrap this functionality up into a bash alias (which is my ultimate goal here), this will cause a weird self-referential situation.
Question: What is an easy way to either have sh -c know the location of my ~/.bashrc profile, or use a variant of sourcing the file and creating an alias?
EDIT: I could save the shell script in my home directory, and create an alias which runs
screen -d -m -S test bash -c '~/mail_submit.sh $1'
but I'd still be curious to hear other possible fixes.
A default ~/.bashrc contains this ([[ "$-" != *i* ]] && return) little piece of code on top of it (or somewhere else in the upper part). This line will prevent the ~/.bashrc from beeing sourced if the bash shell doesn't run in interactive mode.
You could:
Remove this line
Create a new file which will only contain the alias you need and source that
Create a little bash script instead of an alias and run that
Do you mean screen -d -m -S test bash -c 'mail_submit foo'?
It looks like you're trying to run the command with the shell (sh), and not the bourne again shell (bash), which is the shell interpreter which actually reads the ~/.bashrc profile.
Edit: The .bashrc file is not being sourced by default because screen does not create the bash process as a login shell, which is when the .bashrc file is read. Creating a .screenrc file with the line defshell -bash will create the bash process as a login shell instead, which will then call the .bashrc file.

Script to change the directory path

I was trying the below program,
This is a simple script, to cd into a folder
#! /bin/bash
cd /root/
But this below command , doesnt get into the folder
EDITED
#!/bin/bash
alias ex="cd /fs/fm"
alias ex1="source setenv"
alias ex2="cd /fs/fm/tests"
alias ex3="runtest"
To get into /root/ you should make sure that you have permissions. It's accessible if you're running as root itself but if you're running as a normal user you should consider becoming root first. One way is to use sudo:
sudo bash script.sh
And again, make sure your script is in UNIX format. Certainly you can't change to /root/\r.
sed -i 's|\r||' script.sh
dos2unix script.sh
This will never work The script you're running is a separate process, when it finishes you get back to the original environment (cwd, enviroment variables, etc...).
Create an alias:
alias r="cd /root"
or execute the script within your shell:
. myscript
Note: . is a synonym for source.

sudo to a different user and run command as that user

consider this sudo command below
sudo -iu bigadmin
bigadmin is a generic user that all users sudo to, to do stuff with privileged access.
Now the problem is it a shared user like I mentioned. So any kind of profile customization isn't gonna work .
What I am trying to do is for the sessions I establish- I want to run a script that has all my variables inside. so when I sudo it should do these things
sudo -iu bigadmin ; . ./mycustomshell.sh
How's this best done.
First, make sure that all the variables in mycustomshell.sh are exported. Then, source it first, then run sudo -iu bigadmin, so that the shell started by sudo inherits the variables exported by mycustomshell.
Another option is to invoke bash as
sudo -iu bigadmin bash --rcfile mycustomshell.sh
However, this causes bash to ignore .bashrc, so you may want to source .bashrc explicitly at the beginning of mycustomershell.sh to compensate.
This bash command useful for a shell script. It runs a sudo password that given as parameter, and add a line at the end of given file.
echo $password | echo 'net.ipv4.ping_group_range=0 2147483647' | sudo -S tee -a /etc/sysctl.conf

Switching from zsh to bash on OS X, and back again?

I'm learning to develop in Rails, and have discovered the power of zsh. However, for some of my other tasks, I wish to use normal bash.
Although they are the same, I just feel comfortable with the layout of bash in some situations.
How do I switch back and forth, or turn zsh on and off?
You can just use exec to replace your current shell with a new shell:
Switch to bash:
exec bash
Switch to zsh:
exec zsh
This won't affect new terminal windows or anything, but it's convenient.
you can try chsh -s /bin/bash to set the bash as the default,
or chsh -s /bin/zsh to set the zsh as the default.
Terminal will need a restart to take effect.
I switch between zsh and bash somewhat frequently. For a while, I used to have to source my bash_profile every switch. Then I found out you can (typically) do
exec bash --login
or just
exec bash -l
if it is just a temporary switch
you can use exec as mentioned above, but for more of a permanent solution.
you can use chsh -s /bin/bash (to switch to bash) and chsh -s /bin/zsh (to switch to zsh)
For Bash, try
chsh -s $(which bash)
For zsh, try
chsh -s $(which zsh)
In Mac OS Catalina default interactive shell is zsh.
To change shell to zsh from bash:
chsh -s /bin/zsh
Then you need to enter your Mac password. Quit the terminal and reopen it. To check whether it's changed successfully to ssh, issue the following command.
echo $SHELL
If the result is /bin/zsh, your task is completed.
To change it back to bash, issue the following command on terminal.
chsh -s /bin/bash
Verify it again using echo $SHELL. Then result should be /bin/bash.
zsh has a builtin command emulate which can emulate different shells by setting the appropriate options, although csh will never be fully emulated.
emulate bash
perform commands
emulate -R zsh
The -R flag restores all the options to their default values for that shell.
See: zsh manual
you can just type bash or if you always want to use bash:
on "iTerm2"
Go to preferences > Profiles > Command
Select "Command" from the dropdown
Type bash
Test by closing iTerm and open it again
You should be able just to type bash into the terminal to switch to bash, and then type zsh to switch to zsh. Works for me at least.
Follow the below steps !
chsh -s /bin/bash
Restart terminal
check which shell is in use by echo $SHELL
source .profile
You are back with Bash !!
For me, the solution was this:
Edit:
sudo vi /etc/passwd
Find your user, for me it was for example:
ubuntu:x:1000:1001::/home/ubuntu:/bin/sh
For you it might be:
ubuntu:x:1000:1001::/home/ubuntu:/bin/zsh
And change it to:
ubuntu:x:1000:1001::/home/ubuntu:/bin/bash
If you want bash to be defaul, or the line above if you want it to be zsh by default.
You can easily switch back to bash by using command "bye"

Resources