I'm a newbie of zsh.
Could I type something like cd %wiki to jump to ~/prj/golang/gowiki if it's unique.
But if there are more than two directories posible for cd %unix, just show the matching directories.
Here is my sample dirs history.
$ dirs -v
0 ~/prj/golang
1 ~
2 ~/prj/unixconf
3 ~/prj/unixconf/srv
4 ~/memo
5 ~/prj/golang/gowiki
I do not think you can get that without writing a custom version of cd (i.e. creating a function called cd that would take over from the builtin cd.
You could do something like:
DIRSTACKSIZE=20
setopt auto_pushd # Make cd push the old directory onto the directory stack.
setopt pushd_ignore_dups # Ignore duplicates at the directory stack.
setopt pushd_minus # makes the whole pushd list easier to use from 'cd'
Then if you did
% cd -[TAB]
1 -- /tmp
2 -- /etc
You could just use the number:
cd -2 # jumps to /etc
Also notice that you can use the directory stack from other commands (mv, cp etc) through ~-NUMBER
mv notes.txt ~-[TAB]
1 -- /tmp
2 -- /etc
3 -- /my/very/complicated/dir/path
Refer to the zshall meta-manpage (man zshall) for easiest access to learn about many wonderful zsh tricks. Also notable are the zshcontrib and zshmisc manpages.
Here is an excerpt to help make remembering directories in the dirstack easier.
REMEMBERING RECENT DIRECTORIES
The function cdr allows you to change the working directory to a previous
working directory from a list maintained automatically. It is similar in
concept to the directory stack controlled by the pushd, popd and dirs
builtins, but is more config‐ urable, and as it stores all entries
in files it is maintained across sessions and (by default) between
terminal emulators in the current session. (The pushd directory stack is
not actually modified or used by cdr unless you configure it to do so as
described in the configuration section below.)
Installation
The system works by means of a hook function that is called every time
the directory changes. To install the system, autoload the required
functions and use the add-zsh-hook function described above:
autoload -Uz chpwd_recent_dirs cdr add-zsh-hook
add-zsh-hook chpwd chpwd_recent_dirs
Now every time you change directly interactively, no matter which command
you use, the directory to which you change will be remembered in
most-recent-first order.
Use
All direct user interaction is via the cdr function.
The argument to cdr is a number N corresponding to the Nth most recently
changed-to directory. 1 is the immediately preceding directory; the
current directory is remembered but is not offered as a destination.
Note that if you have multiple windows open 1 may refer to a directory
changed to in another window; you can avoid this by having per-terminal
files for storing directory as described for the recent-dirs-file style
below.
If you set the recent-dirs-default style described below cdr will behave
the same as cd if given a non-numeric argument, or more than one
argument. The recent directory list is updated just the same however you
change directory.
If the argument is omitted, 1 is assumed. This is similar to pushd's
behaviour of swapping the two most recent directories on the stack.
Completion for the argument to cdr is available if compinit has been run;
menu selection is recommended, using:
zstyle ':completion:*:*:cdr:*:*' menu selection
to allow you to cycle through recent directories; the order is
preserved, so the first choice is the most recent directory before the
current one. The verbose style is also recommended to ensure the
directory is shown; this style is on by default so no action is required
unless you have changed it.
For named directories, you will want to use the hash -d name=/path and throw it in your zshrc. You can then cd to those directories with cd ~name
Related
I looked up the forum but didn't find an article which matches my problem. Maybe there is some, and you can help me out with it.
My problem is I want to sync an folder with the command rsync -a -v. The point is I got 5 different Maschinen. On every maschine is a scratch folder I want to sync into the folder: ~/work_dir/scratch_maschines and inside the /scratch_maschines folder should be a folder for maschine_a, maschine_b and so on.
On the maschines it is always the same path: /scratch/my_name. So when I use now this command for the first two maschines:
rsync -a -v --exclude='*.chk' --exclude='*.rwf' --exclude='*.fchk' --delete sp02:/scratch/my_name ~/work_dir/scratch_maschine01; rsync -a -v --exclude='*.chk' --exclude='*.rwf' --exclude='*.fchk' --delete maschine02:/scratch/my_name ~/work_dir/scratch_maschine02
I got a folders for scratch_maschine01 and scratch_maschine02 in my working directory but inside these folders are not direct my data there is first a folder inside with my_name and this folder contains the data. So my question is how can I use the rsync command and get the files from the scratch directorys straight to the folders for each machine?
You might want to consider reformulating your commands similar to the following:
START=`pwd`
EXCLUDES="--exclude='*.chk' --exclude='*.rwf' --exclude='*.fchk'"
{ SOURCE="sp02:/scratch/my_name"
REMOTE="${HOME}/work_dir/scratch_maschine01"
cd "${SOURCE}"
rsync --recursive -v --delete ${EXCLUDES} "./" "${REMOTE}/"
}>${START}/job.log 2>${START}/job.err
The key elements there are
the --recursive which will rsync will expand to include all content and subdirs of the SOURCE directory.
the / behind the ${SOURCE} notifies rsync to limit itself to content of the SOURCE directory, but not the directory itself.
the / behind the ${REMOTE} notifies rsync to limit itself to depositing content into that directory and expect it to already exist, to specifically fail if that does not already exist at REMOTE; this ensures that the remote site doesn't attempt a failsafe PWD and deposit files elsewhere than expected.
The above approach lends itself to a function form that could be placed into a loop with pre-attempt condition checks, along with having a complementary case for all variable assignments grouped under a destination heading (i.e. case statements).
Using such an approach with meaningful labels for variables lends itself to a type of implicit documentation, making the code more meaningful to someone not familiar with the code, as well as a refresher for yourself after a long period of not working or using the code.
I try to avoid the "~" because I prefer to always enclose definitions for variables in double quotes, to avoid issues that might arise from paths that may include unexpected characters or spaces. That way, you are sure to have your defined paths correctly interpreted by commands in scripts.
Lastly, I prefer to use the long form for the rsync options (and almost every other command) so that I don't have to refer to the manual every time to translate the single-character options when trying to understand what is coded, if the need arises for troubleshooting unexpected errors (I have always had poor memory).
My own backup command is as follows. The only reason why the
${PathMirror}${dirC}/
is not encapsulated in single quotes within the double quotes for COM is because I know those variables all evaluate to non-complex strings which cannot be misinterpreted.
Using any of the standard Robot libraries, is it possible to recursively copy the contents of a directory to an existing destination directory?
Basically, I'm looking for the equivalent of the following shell command: cp -r foo/. bar (note the trailing dot)
I tried Copy Directory but this creates a directory foo inside bar (as documented) and it doesn't stop doing that even when supplying the trailing dot. Copy Files chokes when it encounters a directory.
Is there anything I overlooked? Or do I need to just call cp -r myself?
As I only need this to work on Linux, I ended up implementing a custom keyword calling cp -r. If this is ever needed cross-platform, then I'll follow the suggestions to directly implement it in Python.
Copy Directory Contents
[Documentation] Recursively copies the contents of the source directory into the destination.
[Arguments] ${source} ${destination}
Directory Should Exist ${source}
Directory Should Exist ${destination}
${result} = Run Process cp -r ${source}/. ${destination}/
Should Be Equal As Integers ${result.rc} 0
My zsh has some completion features I don't understand and can't find where to change. I have two issues where I suspect they have a similar "fix" for my problem. I initialize the zsh completion system with
autoload -Uz compinit
compinit
to get advanced completion features, but I also get the following problems that I don't have without compinit.
First: I happen to have a directory called mydir in my home directory and unfortunately, there is also a user called mydir. When I want to change into my directory and then use tab completion, i.e.
cd mydir/<TAB>
I get the content directories of ~myusername/mydir/ along with all directories available for ~mydir/. I already tried to put
zstyle ':completion:*' users myusername
in my .zlogin file, but it does only change the completion of the username itself and not subsequent directories. Is there some similar switch to turn off completion of other users' home directories? Alternatively, it would already be good if the current directory completion would appear first in the completion menu.
Second: I wrote a script called setup-file-with-a-long-name.sh that resides in my home directory. When I want to execute it via
source setup-file-with-a-long-name.sh
I start with the first few characters, I press <TAB> and I get a list of lots of executable files that are probably somewhere on my $PATH installed by the system, but I don't care about all those files, I just want my file (which is the only match in the current directory) to be displayed either first in the menu and accessible via <TAB> <TAB> or better yet, be accepted after the first <TAB>. (If I select any of them, they don't work anyway because source needs the absolute path, not the filename. Therefore this is a behavior I don't understand and can't see how this is useful as a default for anybody.)
Possible workarounds:
1. Write ~/ explicitly - this is what I want to avoid, because I have to ssh into a new shell pretty often and want to start navigating without thinking about whether I am in $HOME or not.
2. Don't use compinit - well, I like the context-aware completion in principle, I just want to adapt it to my needs.
The following works in bash,
man source -
source filename [arguments]
Read and execute commands from filename in the current shell environment and return the exit status of the last command executed from filename. If filename does not contain a slash, file
names in PATH are used to find the directory containing filename. The file searched for in PATH need not be executable. When bash is not in posix mode, the current directory is searched if
no file is found in PATH. If the sourcepath option to the shopt builtin command is turned off, the PATH is not searched.
to disable the flag instructions are a little above the description of sourcepath
shopt [-pqsu] [-o] [optname ...]
Toggle the values of variables controlling optional shell behavior. With no options, or with the -p option, a list of all settable options is displayed, with an indication of
whether or not each is set. The -p option causes output to be displayed in a form that may be reused as input. Other options have the following meanings:
-s Enable (set) each optname.
-u Disable (unset) each optname.
-q Suppresses normal output (quiet mode); the return status indicates whether the optname is set or unset. If multiple optname arguments are given with -q, the return
status is zero if all optnames are enabled; non-zero otherwise.
-o Restricts the values of optname to be those defined for the -o option to the set builtin.
...
sourcepath
If set, the source (.) builtin uses the value of PATH to find the directory containing the file supplied as an argument. This option is enabled by default.
so executing the following should remove path from your tab completion...
shopt -u sourcepath
I'm doing development on a Wordpress plugin. My development directory contains a lot of development-specific stuff (e.g. Grunt files, Sass files, the git repository itself, etc.).
Obviously, I don't want to distribute this folder containing all of those development files; people don't want a few MB of Grunt files when they download my Wordpress plugin.
Up until now, though, my "release" process has been cumbersome:
Commit the Git changes
Zip the entire folder
Open the zip file and delete the .git folder, grunt files, and all the other development-specific files
Release the new zip
I don't know the best way to accomplish this, but I'm very vaguely familiar with Git hooks, and I had this thought: could I set up a Git hook that would zip ONLY the needed production files into a ZIP file and store it with the repo? That way, every time I commit it would automatically create a new release ZIP.
Is that possible? If so, could someone point me in the right direction?
Oh also, I'm on Windows (・_・;). So I'm hoping that there's a way to do it on Windows.
I can't speak for Windows, but:
It's technically possible to do that sort of thing in a pre-commit hook.
Don't.
A pre-commit hook that modifies "what you will commit" is annoying (if nothing else, it violates the "rule of least astonishment", where your version control system simply stores the versions you tell it to store). Apart from that, storing large pre-compressed binaries interferes with git's attempt to save space in pack files, and will cause rapid repository bloat, poor performance, running out of memory, and so on. A ZIP-archive is a pre-compressed binary and hence will behave badly.
In general, a more reasonable "hook-y" way to handle releases is to set up a "release server" to which you push new releases, and have the push trigger the archive-generation. (There are ways to do this without a separate server / repository, and you can do it in a more pull-style fashion, but the push-style is easy to illustrate.)
[Edit: I had originally considered git archive but did not realize you could get it to exclude files conveniently, so wrote up the below instead. So, jthill's answer is better and should be one's first resort. I'll leave this in place as an alternative for some case where for some reason, git archive might not do.]
For instance, here's a server-side post-receive hook code fragment that checks whether a branch whose name matches release* has been pushed-to, and if so, invokes a shell function with the name of the branch (once for each such branch):
#! /bin/sh
NULL_SHA1=0000000000000000000000000000000000000000
scan()
{
local oldsha newsha fullref shortref
local optype
while read oldsha newsha fullref; do
case $oldsha,$newsha in
$NULL_SHA1,*) optype=create;;
*,$NULL_SHA1) optype=delete;;
*) optype=update;;
esac
case $fullref in
refs/heads/*)
reftype=branch
shortref=${fullref#refs/heads/}
;;
*)
reftype=other
shortref=fullref
;;
esac
case $optype,$reftype,$shortref in
create,branch,release*|update,branch,release*)
do_release $shortref;;
esac
done
}
scan
(much of the above is boilerplate, which I have stripped down to essentials). You would have to write the do_release function, which might resemble (totally untested):
do_release()
{
local tmpdir=/tmp/build.$$ # or use mktemp -d
# $tmpdir/index is git's index; $tmpdir/t is the work tree
trap "rm -rf $tmpdir; exit 1" 1 2 3 15
rm -rf $tmpdir
mkdir $tmpdir/t
GIT_INDEX_FILE=$tmpdir/index GIT_WORK_TREE=$tmpdir/t git checkout $1
# now clean out grunt files and make zip archive
(cd $workdir/t; rm -rf grunt; zip ../t.zip .)
# put completed zip archive in export location, name it
# based on the branch name
mv $workdir/t.zip /place/where/zip/files/live/$1.zip
# clean up temp dir now, and no longer need to clean up
# on signal related abort
rm -rf $tmpdir
trap - 1 2 3 15
}
There's actually a command for this, git archive.
git archive master -o wizzo-v1.13.0.zip
See the EXAMPLES section, you can select paths, add prefixes to them, define custom postprocessing by output extension, and some more minor tweaks.
Also see the ATTRIBUTES section: you can give files -- arbitrary patterns, really -- an export-ignore attribute to exclude them from archives.
It's got a bunch more handy-dandies, you can get archives from remote repos, expand arbitrary git log --pretty=format: placeholders, the git manpages are definitely worth whatever time you can invest in them.
So this doesn't seem like a terribly complicated question I have, but it's one I can't find the answer to. I'm confused about what the -p option does in Unix. I used it for a lab assignment while creating a subdirectory and then another subdirectory within that one. It looked like this:
mkdir -p cmps012m/lab1
This is in a private directory with normal rights (rlidwka). Oh, and would someone mind giving a little explanation of what rlidwka means? I'm not a total noob to Unix, but I'm not really familiar with what this means. Hopefully that's not too vague of a question.
The man pages is the best source of information you can find... and is at your fingertips: man mkdir yields this about -p switch:
-p, --parents
no error if existing, make parent directories as needed
Use case example: Assume I want to create directories hello/goodbye but none exist:
$mkdir hello/goodbye
mkdir:cannot create directory 'hello/goodbye': No such file or directory
$mkdir -p hello/goodbye
$
-p created both, hello and goodbye
This means that the command will create all the directories necessaries to fulfill your request, not returning any error in case that directory exists.
About rlidwka, Google has a very good memory for acronyms :). My search returned this for example: http://www.cs.cmu.edu/~help/afs/afs_acls.html
Directory permissions
l (lookup)
Allows one to list the contents of a directory. It does not allow the reading of files.
i (insert)
Allows one to create new files in a directory or copy new files to a directory.
d (delete)
Allows one to remove files and sub-directories from a directory.
a (administer)
Allows one to change a directory's ACL. The owner of a directory can always change the ACL of a directory that s/he owns, along with the ACLs of any subdirectories in that directory.
File permissions
r (read)
Allows one to read the contents of file in the directory.
w (write)
Allows one to modify the contents of files in a directory and use chmod on them.
k (lock)
Allows programs to lock files in a directory.
Hence rlidwka means: All permissions on.
It's worth mentioning, as #KeithThompson pointed out in the comments, that not all Unix systems support ACL. So probably the rlidwka concept doesn't apply here.
-p|--parent will be used if you are trying to create a directory with top-down approach. That will create the parent directory then child and so on iff none exists.
-p, --parents
no error if existing, make parent directories as needed
About rlidwka it means giving full or administrative access. Found it here https://itservices.stanford.edu/service/afs/intro/permissions/unix.
mkdir [-switch] foldername
-p is a switch, which is optional. It will create a subfolder and a parent folder as well, even if parent folder doesn't exist.
From the man page:
-p, --parents no error if existing, make parent directories as needed
Example:
mkdir -p storage/framework/{sessions,views,cache}
This will create subfolder sessions,views,cache inside framework folder irrespective of whether 'framework' was available earlier or not.
PATH: Answered long ago, however, it maybe more helpful to think of -p as "Path" (easier to remember), as in this causes mkdir to create every part of the path that isn't already there.
mkdir -p /usr/bin/comm/diff/er/fence
if /usr/bin/comm already exists, it acts like:
mkdir /usr/bin/comm/diff
mkdir /usr/bin/comm/diff/er
mkdir /usr/bin/comm/diff/er/fence
As you can see, it saves you a bit of typing, and thinking, since you don't have to figure out what's already there and what isn't.
Note that -p is an argument to the mkdir command specifically, not the whole of Unix. Every command can have whatever arguments it needs.
In this case it means "parents", meaning mkdir will create a directory and any parents that don't already exist.