What does the "-Np1" option for the patch command do? - unix

Someone sent me a patch and told me to apply it using the command:
patch -Np1 -i file.patch
Out of curiosity, I tried to find out what the -Np1 option does but the patch man page is curiously opaque on this. Can anyone explain what this does? Thanks.

It's two flags. -N and -p1.
-N or --forward
Ignore patches that seem to be reversed or already applied. See
also -R.
and
-pnum or --strip=num
Strip the smallest prefix containing num leading slashes from each
file name found in the patch file. A sequence of one or more adja-
cent slashes is counted as a single slash. This controls how file
names found in the patch file are treated, in case you keep your
files in a different directory than the person who sent out the
patch. For example, supposing the file name in the patch file was
/u/howard/src/blurfl/blurfl.c
setting -p0 gives the entire file name unmodified, -p1 gives
u/howard/src/blurfl/blurfl.c
without the leading slash, -p4 gives
blurfl/blurfl.c
and not specifying -p at all just gives you blurfl.c. Whatever you
end up with is looked for either in the current directory, or the
directory specified by the -d option.

Related

How can I change PATH variable in zsh?

I want to change my PATH variable in zsh.
Problem: I don't understand where in the .zshrc file I have to make modifications.
Normally, I would look for the assignment to the PATH variable and set the values from scratch how I would like them to be (leaving all the systems binaries directories untouched).
The first lines in my .zshrc file are as follows:
# If you come from bash you might have to change your $PATH.
# export PATH=$HOME/bin:/usr/local/bin:$PATH
# Path to your oh-my-zsh installation.
export ZSH="/Users/Sam/oh-my-zsh"
export PATH=$PATH:/Applications/Postgres.app/Contents/Versions/13/bin
etc.
My actual PATH variable is:
/Library/Frameworks/Python.framework/Versions/3.9/bin:/Library/Frameworks/Python.framework/Versions/3.8/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Applications/Postgres.app/Contents/Versions/13/bin
I want to delete the directory where python3.8 is in, it's redundant.
My questions:
Do I have to change line 2 or line 7 in my .zshrc file?
Line 2 is commented out...is it executed anyway at the start of the terminal?
I have tried to comment out line 7. But the postgres directory still remained in my PATH variable which I don't understand.
The .zshrc is located in the home dir. The dot at the beginning keeps it hidden. Type ls -a from ~ directory to see it. To edit just run vim, nvim, etc as usual.
nvim ~/.zshrc
This is the command for Neovim. For your editor, sub nvim for the proper command.
Once you get in, you need only add the same export command that you would add from the command line.
export PATH=$PATH:/whatever/you/are/adding
EDIT
To remove a path variable:
First, run the command:
echo $PATH
from the command line.
Next, Copy the output to clipboard.
Finally, at the very end of the .zshrc file, add the following:
export PATH=<paste-what-you-copied-here>
Because you didn't reference $PATH after the =, this will set the path to EXACTLY what you pasted, no more, no less. Adding $PATH: as in the first example will just add whatever to the end of what is already there.
Since this gives you access to every item in the path array, deleting is just a matter of a literal highlight/select and of whatever you want deleted.
Finally, be sure that there is only one place in the file where you are editing PATH. If there are more than one, the result can be confusing to say the least.
That said, I believe the script runs top-to-bottom, so only the last mention should persist. You can take advantage of this in some situations, but for this purpose, one will suffice. XD
Be careful when you decide to fiddle with the PATH in .zshrc: Since the file is processed by every interactive subshell, the PATH would get longer and longer for each subshell, with the same directory occuring in it several times. This can become a nightmare if you later try to hunt down PATH-related errors.
Since you are using zsh, you can take advantage that the scalar variable PATH is mirrored in the array variable path, and that you can ask zsh to keep entries in arrays unique.
Hence, the first thing I would do is put a
typeset -aU path
in your .zshrc; this (due to mirroring) also keeps the entries in PATH unique. You can put this statement anywhere, but I have it for easier maintenance before my first assignment to PATH or path.
It is up to you to decide where exactly you add a new entry to PATH or path. The entries are searched in that order which is listed in the variable. You have to ask yourself two questions:
Are some directories located on a network share, where you can sometimes expect access delays (due to bad network conditions)? Those directories should better show up near the end of the path.
Do you have commands which occur in more than one directoryin your path? In this case, a path search will always find the first occurance only.
Finally, don't forget that your changes will be seen after zsh processes the file. Therefore, you could create a new subshell after having edited the file, or source .zshrc manually.

How to use include and exclude precedence with rsync?

I'm trying to backup a machine using rsync and after reading numerous SO QAs and the man pages, I'm still failing to understand how include/exclude precedence works so I can transfer the right set of files. Obfuscating the specific details, I'm attempting the following:
Include rescursively:
/home/erik/foo
/home/erik/bar
/home/erik/baz
Include /git rescursively, but exclude some specific subdirs, like /git/src/github.com/foo and /git/src/github.com/bar.
So far, the rsync command I think should accomplish this. It does not, and I've tried a number of variations that fail in different ways:
rsync -am \
--include='*/' \
--include='/home/erik/foo' \
--include='/home/erik/bar' \
--include='/home/erik/baz' \
--include='/git' \
--exclude='/git/bin' \
--exclude='/git/src/github.com/foo' \
--exclude='/git/src/github.com/bar' \
--exclude='*' \
/ nfs.example.com:/data/pool/backup/laptop
Some specific questions:
I have seen it suggested many times that the initial --include='*/ is necessary, although I'm not entirely sure why. I gather it has something to do with ensuring directories are expanded and followed(?). I also assume the final exclude is what excludes any file that doesn't match on the higher statements? Could someone elaborate on whether or not these are both necessary, and their positions are significant?
I am unsure whether or not the directories need leading /. I have seen hints that these paths are relative to the requested transfer root of /, which would suggest it should be something like home/erik, but I have not had success with this either. Could someone expand on how this works?
I'm unsure if a suffix / is required in the paths if I want to include the directory and all subcontents?
Could someone elaborate on whether or not the position of the params is actually significant, i.e., the first in the list to match will be applied?
Is there any reason I should prefer --filter='+ X' over --include? Same for exclude?
I'm unsure if there's a more native way to cross post an answer, but I asked on Stack Exchange and got this excellent answer that solved what I was trying to do perfectly, with context.

Handling "?" character passed to ZSH function

I'm having problem with setting up simple function in ZSH.
I want to make function which downloads only mp3 file from youtube.
I used youtube-dl and i want to make simple function to make that easy for me
ytmp3(){
youtube-dl -x --audio-format mp3 "$#"}
So when i try
ytmp3 https://www.youtube.com/watch?v=_DiEbmg3lU8
i get
zsh: no matches found: https://www.youtube.com/watch?v=_DiEbmg3lU8
but if i try
ytmp3 "https://www.youtube.com/watch?v=_DiEbmg3lU8"
it works.
I figured out that program runs (but wont download anything) if i remove all charachers after ? including it. So i guess that this is some sort of special character for zsh.
By default, the ZSH will try to "glob" patterns that you use on command lines (it will try to match the pattern to file names). If it can't make a match, you get the error you're getting ("no matches found").
You can disable this behaviour by disabling the nomatch option:
unsetopt nomatch
The manual page describes this option as follows (it describes what happens when the option is enabled):
If a pattern for filename generation has no matches, print an error, instead of leaving it unchanged in the argument list.
Try again with the option disabled:
$ unsetopt nomatch
$ ytmp3 https://www.youtube.com/watch?v=_DiEbmg3lU8
If you want to permanently disable the option, you can add the disable command to your ~/.zshrc file.
The question mark is part of ZSH's pattern matching, similarly to *. It means "Any character".
For instance, ls c?nfig will list both "config" and "cinfig", provided they exist.
So, yes, your problem is simply that zsh is trying to interpret the ? in the URL as a pattern to match to files, failing to find any, and crapping out. Escape the ? with a \ or put quotes around it, like you did, to fix it.

Dumbed down patch command

I would like to issue a patch command which is somewhat dumber than the default, but I cannot find the right flags (if they exist at all).
I don't want it to create .rej or .orig files, not even when the patch fails. If the patch fails I'd like the original files to remain unchanged.
I don't want it to try guessing if the patch is reversed or not, or try matching the lines before or after those given in the patch. If the lines at the given line numbers do not match, it should fail.
I've tried with -f -N -V never -r - --no-backup-if-mismatch, but still backup files are created and "fuzzy" matching is tried.
Run it with --dry-run -s and only apply if it doesn't report any problems (you may be able to key off the return code).
For disabling the fuzz, you need -F0

Unix wildcard selectors? (Asterisks)

In Ryan Bates' Railscast about git, his .gitignore file contains the following line:
tmp/**/*
What is the purpose of using the double asterisks followed by an asterisk as such: **/*?
Would using simply tmp/* instead of tmp/**/* not achieve the exact same result?
Googling the issue, I found an unclear IBM article about it, and I was wondering if someone could clarify the issue.
It says to go into all the subdirectories below tmp, as well as just the content of tmp.
e.g. I have the following:
$ find tmp
tmp
tmp/a
tmp/a/b
tmp/a/b/file1
tmp/b
tmp/b/c
tmp/b/c/file2
matched output:
$ echo tmp/*
tmp/a tmp/b
matched output:
$ echo tmp/**/*
tmp/a tmp/a/b tmp/a/b/file1 tmp/b tmp/b/c tmp/b/c/file2
It is a default feature of zsh, to get it to work in bash 4, you perform:
shopt -s globstar
From http://blog.privateergroup.com/2010/03/gitignore-file-for-android-development/:
(kwoods)
"The double asterisk (**) is not a git thing per say, it’s really a linux / Mac shell thing.
It would match on everything including any sub folders that had been created.
You can see the effect in the shell like so:
# ls ./tmp/* = should show you the contents of ./tmp (files and folders)
# ls ./tmp/** = same as above, but it would also go into each sub-folder and show the contents there as well."
According to the documentation of gitignore, this syntax is supported since git version 1.8.2.
Here is the relevant section:
Two consecutive asterisks (**) in patterns matched against full pathname may have special meaning:
A leading ** followed by a slash means match in all directories. For example, **/foo matches file or directory foo anywhere, the
same as pattern foo. **/foo/bar matches file or directory bar
anywhere that is directly under directory foo.
A trailing /** matches everything inside. For example, abc/** matches all files inside directory abc, relative to the location of
the .gitignore file, with infinite depth.
A slash followed by two consecutive asterisks then a slash matches zero or more directories. For example, a/**/b matches a/b,
a/x/b, a/x/y/b and so on.
Other consecutive asterisks are considered invalid.

Resources