does bash script set variables by reference? - bash

I'm trying to get some new aliases set and came across a strange one.
alias l="ls"
alias ls="ls -alGh"
I'd like to shorten the default file list to L and set an all info one to the default, LS, but all I ever get is:
~ Desktop $ unalias ls
~ Desktop $ unalias l
~ Desktop $ source ~/.bash_aliases
~ Desktop $ l
total 8
drwxr-xr-x 3 astagl staff .
drwxr-xr-x 34 astagl staff ..
-rw-r--r-- 1 astagl staff 2015-06-07_10.50.54.inline editor.html
~ Desktop $ ls
total 8
drwxr-xr-x 3 astagl staff .
drwxr-xr-x 34 astagl staff ..
-rw-r--r-- 1 astagl staff 2015-06-07_10.50.54.inline editor.html
~ Desktop $
Directory listing above: I'm clearing out the aliases first, just to start over and source my alias script which includes the first listed code block. Is there some kind of weird variable referencing going on here?
Solution
using the backsplashes seems to do the trick:
alias l="\ls -a"
alias ls="\ls -al"

When expanding an alias, other aliases may be invoked recursively. To avoid that you need to escape the commands in the aliases using a backslash:
alias l="\ls"
alias ls="\ls -alGh"

Related

Creating a new Linux Command without touching the bashrc

I want to write a shell script that allows me to do this in the bash terminal :
Mycommand [options] [param] .
Is there any way that my shell would recognize Mycommand without having to modify the .bashrc ? ( the goal here is to be able to give the script file to someone and they wouldn't have to add anything to their path and still be able to use it as said )
They can run the script by running it from the directory where it is saved:
cd dir/with/script
./script.sh
Or
~/bin/script.sh
If the script is saved in the bin directory in the home of the user.
Define a shell alias. For example, the following alias is called x and it executes ls -alF *.py:
$ alias x="ls -alF *.py"
No files need to be written in order for a shell alias to be defined or used.
Now you can type x into a shell prompt in the shell where you defined the alias, and it will return a detailed list of your Python source files.
$ alias x="ls -alF *.py"
$ x
-rwxrwxr-x 1 mslinn mslinn 653 Feb 19 17:19 django-admin.py*
-rwxrwxr-x 1 mslinn mslinn 1675 Sep 19 2020 jp.py*
-rwxrwxr-x 1 mslinn mslinn 594 Sep 19 2020 rst2html.py*
-rwxrwxr-x 1 mslinn mslinn 6413 Sep 19 2020 wsdump.py*
If you want to be able to specify the pattern for the files to list, do not include that in the alias. For example:
$ alias y="ls -alF"
$ y *.md
-rw-rw-r-- 1 mslinn mslinn 606 Nov 17 20:31 README.md
You can even just define default parameters, and add more:
$ alias z="ls -a"
$ z -lF *.md
-rw-rw-r-- 1 mslinn mslinn 606 Nov 17 20:31 README.md
Your script can call a script within the same folder, to add an alias to the bash session and create variables for your script to run, this would be available for the duration of the bash session. Once you have ended this bash session, the alias and the variables, the script created would be lost.

Does git create new files during merge or overwrite existing ones

I have a script test.sh
#!/bin/bash
echo start old file
sleep 20
echo end old file
in the repository which I do execute, and in the mean time I git merge other-branch changes like
#!/bin/bash
echo start new file
sleep 20
echo end new file
into the current branch.
It seems that git on Unix (?) does not directly overwrite the existing file node (?) and does instead rm test.sh and creates the new file.
In that way its guaranteed that the script execution will always read the initial file test.sh and terminate with echo end old file.
Note: On my system (Ubuntu 20.04), while executing the script and directy overtwriting the content in an editor, results in executing the new code, which is bad...
Is that correct and is it also correct on Windows with git-for-windows?
I can't answer regarding Windows, but on Ubuntu 18.04 I can confirm that a git checkout or git merge will delete and recreate a changed file, rather than editing it in place. This can be seen in strace output, for example:
unlink("test.sh") = 0
followed later by
openat(AT_FDCWD, "test.sh", O_WRONLY|O_CREAT|O_EXCL, 0666) = 4
It can also be seen if you create a hard link to the file before the git command and then look again afterwards, you will see that you have two different inodes, with different contents. This is to be expected following deletion and recreation, whereas an in-place edit would have preserved the hard linking.
$ ls -l test.sh
-rw-r--r-- 1 myuser mygroup 59 Jun 5 17:04 test.sh
$ ln test.sh test.sh.bak
$ ls -li test.sh*
262203 -rw-r--r-- 2 myuser mygroup 59 Jun 5 17:04 test.sh
262203 -rw-r--r-- 2 myuser mygroup 59 Jun 5 17:04 test.sh.bak
$ git merge mybranch
Updating 009b964..d57f33a
Fast-forward
test.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
$ ls -li test.sh*
262219 -rw-r--r-- 1 myuser mygroup 70 Jun 5 17:05 test.sh
262203 -rw-r--r-- 1 myuser mygroup 59 Jun 5 17:04 test.sh.bak
You mentioned in a comment attached to the question that it is related to Overwrite executing bash script files. Although it would seem not to be the best idea to run a git command affecting a script which is currently still being executed, in fact the delete and recreate behaviour should mean that the existing execution will be unaffected. Even if the bash interpreter has not yet read the whole file into memory, it will have an open filehandle on the existing inode and can continue to access its contents even though that inode is no longer accessible via the filename that it had. See for example What happens to an open file handle on Linux if the pointed file gets moved or deleted
On Windows with git-for-windows I see the same behavior:
$ mklink /H test.sh.bak
$ fsutil hardlink list test.sh.bak
test.sh.bak
test.sh
$ git merge test
$ fsutil hardlink list test.sh.bak
test.sh.bak
Meaning the hard link did not get preserved, meanin a new file has been created.

Messed up my bash_profile and bashrc files - reset to default?

I think I messed up my .bash_profile and .bashrc file.
Is there any way I can reset them to default?
When I want to access them through the terminal I get: Permission denied.
If I open them using sublime text, my .bashrc is completely empty and my .bash_profile contains the following code:
PATH="/Library/Frameworks/Python.framework/Versions/3.8/bin:${PATH}"
export PATH=/usr/local/bin:$PATH
alias python=python3
alias sublime="open -a /Applications/Sublime\ Text.app"
source ~/.profile
Any idea on what I could add/delete to any of the files?
Python does not run properly anymore since I accidentally played around on those files.
You may find the default .bash_profile and .bashrc files in /etc/skel/
[user#server /]$ ls -la /etc/skel
total 28
drwxr-xr-x. 3 root root 78 Jan 3 2019 .
drwxr-xr-x. 131 root root 12288 Nov 7 13:03 ..
-rw-r--r--. 1 root root 18 Oct 30 2018 .bash_logout
-rw-r--r--. 1 root root 193 Oct 30 2018 .bash_profile
-rw-r--r--. 1 root root 231 Oct 30 2018 .bashrc
If it's the case you can get them back:
cp /etc/skel/.bash_profile /etc/skel/.bashrc ~/
Make a backup of your current files before ;)
Just to explain: the content of /etc/skel/ is copied into the home directory of a user when created with adduser.

Set runtimepath for vim in command line alias

I want to set an alias for vim so that when I use vim I want all my personal vim files to be sourced. (I want to do this because the machine I use is used by everyone else, so I don't want to affect others' usage. The alias is also set only when I login into the machine)
alias vim='vim -c "source ~/.dc_dotfiles/.vimrc_dc" --cmd "set rtp+=~/.dc_dotfiles/.vim"'
But this is not working as files in ~/.dc_dotfiles/.vim are not being sourced.
Here are the contents of ~/.dc_dotfiles/.vim folder
~$ ls -lhart .dc_dotfiles/.vim/plugin/
total 20K
-rw-r--r-- 1 veveo veveo 18K Oct 18 17:34 abolish.vim
drwxr-xr-x 3 veveo veveo 19 Oct 18 17:35 ..
drwxr-xr-x 2 veveo veveo 24 Oct 18 17:35 .
When I am using the screen I set a flag that will let know if I am logged in. I added this part to my ~/.vimrc
if !empty($DCSCREENFLAG)
set rtp+=~/.dc_dotfiles/.vim
endif
If the flag is set, it means that I am logged in and using the screen, so go ahead and add the directory to the runtimepath.

Modifying /private/etc/paths did not change $PATH after a reboot

On a rMBP here. I'm not sure what the script is that is responsible for doing this. Basically I want to add the path to python utils to the $PATH...
For example, I brewed python brew python in order to get pip, then ran pip install flake8. Now
$ which flake8
flake8 not found
$ find / | grep flake8
...
......
/usr/local/share/python/flake8
$ ls -la /usr/local/share/python/
total 32
drwxr-xr-x 6 lust admin 204 Apr 2 18:15 .
drwxr-xr-x 15 lust admin 510 Apr 2 18:12 ..
lrwxr-xr-x 1 lust admin 45 Apr 2 18:13 Extras -> ../../Cellar/python/2.7.3/share/python/Extras
-rwxr-xr-x 1 lust admin 389 Apr 2 18:15 flake8
-rwxr-xr-x 1 lust admin 385 Apr 2 18:15 pep8
-rwxr-xr-x 1 lust admin 405 Apr 2 18:15 pyflakes
Alright!
$ cat /private/etc/paths
/usr/bin
/bin
/usr/sbin
/sbin
/usr/local/bin
$ sudo vim /private/etc/paths
$ cat /private/etc/paths
/usr/bin
/bin
/usr/sbin
/sbin
/usr/local/bin
/usr/local/share/python
Make a new shell, check $PATH, python not there. Okay.
Reboot, start a new shell, check $PATH, python still not there.
Oh, by the way, the solution is not to append, with anything like export PATH=$PATH:newpath, because I don't actually care to run flake8 from the command-line, I want Sublime Text 3' SublimeLinter plugin to actually know where it is without putting some hacky config in the settings for the editor.
I found the problem. As part of oh-my-zsh, zsh is set up to set PATH in the ~/.zshrc. I failed to consider this. When starting ST3 without using the command line invocation, it gains its own (incorrect) path environment variable, so that part still doesn't work. The ultimate resolution to the problem, however, is here.

Resources