Symlink and hide dotfiles - unix

How could I rename a bunch of dotfiles and add the leading dot in the same command? I see people writing:
ln -s vimrc .vimrc
ln -s gitconfig .gitconfig
But I would like something like this:
ln -s {vimrc,gitconfig} ~/.$1

Using for loop:
for f in vimrc gitconfig; do ln -s $f .$f ; done
If you have the filename list in a file:
for f in `cat filename_list.txt`; do mv $f .$f ; done

Related

Rsync skip folder based on wildcard

Script:
ash-4.4# cat rsync-backup.sh
#!/bin/sh
# Usage: rsync-backup.sh <src> <dst> <label>
if [ "$#" -ne 3 ]; then
echo "$0: Expected 3 arguments, received $#: $#" >&2
exit 1
fi
if [ -d "$2/__prev/" ]; then
rsync -azP --delete --link-dest="$2/__prev/" "$1" "$2/$3"
else
rsync -azP "$1" "$2/$3"
fi
rm -f "$2/__prev"
ln -s "$3" "$2/__prev"
How can I change this that it skip specific folders based on a wildcard?
This folder should be skipped always:
home/forge/*/storage/framework/cache/*
home/forge/*/vendor
home/forge/*/node_modules
But how can this be achieved? What to change in the original rsync-backup.sh file?
This is not working:
rsync -azP "$1" "$2/$3" --exclude={'node_modules', 'cache','.cache','.npm','vendor','.git'}
The --exclude={'dir1','dir2',...} does not work under sh shell. It works only under bash.
Your options are:
use bash, then the --exclude={'node_modules', 'cache','.cache','.npm','vendor','.git'} will work.
use multiple --exclude switches like: --exclude= statements. For example, rsync <params> --exclude='node_modules' --exclude='cache' --exclude='.cache' ...
use --exclude-from, where you have a text file with list of excluded directories. Like:
rsync <params> --exclude-from='/home/user/excluded_dir_list.txt' ...
The file excluded_dir_list.txt would contain one excluded dir for line like:
node_modules
cache
.cache
.npm
vendor
.git

How to get non-recursive list of directory contents with their paths in Makefile?

My project's directory structure is as follows:
My Makefile looks like this:
dir1_contents = $(shell ls dir1/*)
dir3_contents = $(shell ls dir3/*)
all: clean_dir1 clean_dir3
clean_dir1:
echo 'dir1_contents = $(dir1_contents)'
clean_dir3:
echo 'dir3_contents = $(dir3_contents)'
When I run make, this is what I get:
$ pwd
make-test
$ make -s
dir1_contents = dir1/file2.junk dir1/dir2: file1.junk
dir3_contents = dir3/file3.junk
I want to get the contents of dir1 in dir1_contents. But I don't want the recursive contents. Just the contents that are immediately below the dir1 directory. How can I do it?
If I remove the /* from the first two lines of the Makefile, I get the right contents I want. But then they are missing their paths which I also need:
$ pwd
make-test
$ make -s
dir1_contents = dir2 file2.junk
dir3_contents = file3.junk
How can I get the right contents I want with the file paths that I need also?
The problem you're having is related to the way ls works, it's nothing to do with GNU make. If you run ls dir1/* then the shell expands the wildcard before invoking ls, so this is the same as running:
ls dir1/dir2 dir1/file2.junk
And when you ls a directory it shows the contents of the directory by default, so the output is:
$ ls dir1/dir2 dir1/file2.junk
dir1/file2.junk
dir1/dir2:
file1.junk
(go ahead and try this at the command prompt). Since that's what the shell prints, that's the result you get back.
If you just want to see the directories but not the files in the directories, you can add the -d option to the ls command:
$ ls -d dir1/dir2 dir1/file2.junk
dir1/file2.junk dir1/dir2
Or, in the makefile:
dir1_contents = $(shell ls -d dir1/*)
dir3_contents = $(shell ls -d dir3/*)
However, I think this is not a great way to do it anyway. Why not use GNU make's built-in wildcard function instead? In addition to being simpler to understand it's a LOT more portable and much more efficient (the above version requires invoking a shell and the ls program). I also recommend you use := not =, so that you only perform the wildcard operation one time:
dir1_contents := $(wildcard dir1/*)
dir3_contents := $(wildcard dir3/*)

Unix Copy Recursive Including All Directories

I have the following two directories:
~/A
drawable/
imageb.png
new/`
newimage.png
~/B
drawable/
imagec.png
When I use the cp -r ~/A/* ~/B command newimage.png with its new/ folder is copied across to ~/B however imageb.png is not copied into ~/B/drawable.
Could you explain why this is the case and how I can get around this?
Use tar instead of cp:
(cd A ; tar cf - *) | (cd B ; tar xf -)
or more compactly (if you're using GNU tar):
tar cC A -f - . | tar xC B -f -
If you are on linux you can use the -r option.
eg: cp -r ~/A/. ~/B/
If you are on BSD you could use the -R option.
eg: cp -R ~/A/. ~/B/
For more information on exactly what option you should pass, refer man cp
Also note that, if you do not have permissions to the file you it would prevent copying files.

ln with dotfiles?

I have a directory with several "dot files". I would like to symlink all these files.
I tried
$ ln -s /usr/dotfiles/* /usr/test
ln: creating symbolic link `/usr/test/*' to `/usr/dotfiles/*': No such file or directory
ln -s /usr/dotfiles/.[!.]* /usr/test
Inspired from
pavium’s answer

Unable to make symlinks effectively with target files of the same names

I have a list of dotFiles at my workarea. For example, .bashrc and .vimrc.
I want to make a symlinks from them to my Home such that their names are the same as in my workarea -folder.
My attempt in pseudo-code
ln workarea/.[a-zA-Z] ~/.*
The problem is to have a bijection from [a-zA-Z] to the files which occur in my Home.
How can you make symlinks with the target files of same name as the original files?
'man ln' says:
ln [OPTION]... TARGET... DIRECTORY (3rd form)
So you need to do something like:
$ ln -s workarea/.* ~/
The possible uses of ln to create symbolic link(s) are:
ln -s <source-file> [<target-file]>
ln -s <source-file> ... <target-dir>
When you type
ln -s workarea/.[a-zA-Z]* ~/.*
(I think you were missing a *) the shell will expand out workarea/.[a-zA-Z] and ~/.*, so (presuming that the your HOME directory contains the files .abc and .def) you would end up with
ln -s workarea/.bash_profile workarea/.bashrc ~/.abc ~/.def
which fits neither usage of ln.
To use the second usage of ln, you would use:
ln -s workarea/.[a-zA-Z]* ~/.

Resources