Recursively copy the *contents* of a directory - robotframework

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

Related

cp command unix error

I am trying to copy files from another user on a server over to my user.
my command is:
cp /Directory/*
cp: target /Directory/file1.txt is not a directory
What is wrong?
I want to copy all files in the "Directory"
Simple answer: You haven't provided a destination, i.e. a target where to put files.
Long answer:
cp needs two or more arguments. All arguments except the last are treated as source, the last is treated as target.
When you write cp /Directory/*, then /Directory/* is expanded to a list of all files in the directory.
Therefore cp tries to copy all files in the directory, except the last one, into the last one. But that one is not a directory, therefore the command fails.

How do I create a directory with a file in it, in one step?

In the terminal, is there a way to create a directory with a file in it in one step?
Currently I do this in 2 steps:
1. mkdir foo
2. touch foo/bar.txt
Apparently, touch foo/bar.txt doesn't work.
With only standard unix tools, the most direct way to create a directory and a file in this directory is
mkdir foo && touch foo/bar.txt
Unix is built around the philosophy of simple, single-purpose tools with the shell as a glue to combine them. So to create a directory and a file, you instruct a shell to run the directory creation utility then the file creation utility.
I won't swear that there isn't some bizarre way of using a standard tool that lets you do it with a single command. (In fact, there is: unpack an archive — except that you'll need to provide that archive as a file, with predefined owner, date and other metadata, or else use another command to build an archive.) But whatever it is would be convoluted.

How to copy a entire directory which contains symlinks?

I want to copy a complete directory content from /home/private_html/userx/ into the /home/private_html/usery/, the problem is that the directory userx contains few symlinks, and when using the cp it just skip them (skip occurs, if symlinks directs into a file, in case if it points into the directory, it just copy WHOLE directory instead...).
The command I was using looks following:
# cp -iprv /home/private_html/userx/ /home/private_html/usery/
Has anyone a solution to copy the directory "just as it is" into other place?
On FreeBSD, cp doesn't have an -r option. It does have -R, which should do what you want:
-R If source_file designates a directory, cp copies the directory and
the entire subtree connected at that point. If the source_file
ends in a /, the contents of the directory are copied rather than
the directory itself. This option also causes symbolic links to be
copied, rather than indirected through, and for cp to create spe‐
cial files rather than copying them as normal files. Created
directories have the same mode as the corresponding source direc‐
tory, unmodified by the process' umask.
Roland is right about the -R flag. You could also use a pair of tar-processes, which would make your command a little bit more system-independent:
tar -C /home/private_html/userx/ -cpf - . | tar -C /home/private_html/usery/ -epf -

Can zsh chdir search and match history?

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

`(cd X; pwd)` sometimes returns two-line

I have shell script which starts with:
sdir=`dirname $0`
sdir=`(cd "$sdir/"; pwd)`
And this usually gets expanded (with 'sh -h') into
++ dirname /opt/foo/bin/bar
+ sdir=/opt/foo/bin
++ cd /opt/foo/bin/
++ pwd
+ sdir=/opt/foo/bin
but for single user for single combination of parameters in expands into (note two lines at the result sbin value)
++ dirname bin/foo
+ sdir=bin
++ cd bin/
++ pwd
+ sdir='/opt/foo/bin
/opt/foo/bin'
I tried different combinations but was not able to reproduce this behavior. With different input parameters for that user it started producing correct single line result. I am new to shell scripting, so please advice when such (cd X; pwd) can return two line.
it was observed on CentOS, but not sure it that matters. Please advice.
The culprit is cd, try this instead
sdir=`dirname $0`
sdir=`(cd "$sdir/" >/dev/null; pwd)`
This happens because when you specify a non absolute path and the directory is found in the environment variable CDPATH, cd prints to stdout the value of the absolute path to the directory it changed to.
Relevant man bash sections:
CDPATH The search path for the cd command. This is a
colon-separated list of directories in which the
shell looks for destination directories specified
by the cd command. A sample value is ``.:~:/usr''.
cd [-L|-P] [directory]
Change the current working directory to directory. If
directory is not given, the value of the HOME shell
variable is used. If the shell variable CDPATH exists,
it is used as a search path. If directory begins with a slash,
CDPATH is not used.
The -P option means to not follow symbolic links; symbolic
links are followed by default or with the -L option. If
directory is ‘-’, it is equivalent to $OLDPWD.
If a non-empty directory name from CDPATH is used, or if ‘-’
RELEVANT -\ is the first argument, and the directory change is successful,
PARAGRAPH -/ the absolute pathname of the new working directory is written
to the standard output.
The return status is zero if the directory is successfully
changed, non-zero otherwise.
OLDPWD The previous working directory as set by the cd
command.
CDPATH is a common gotcha. You can also use "unset CDPATH; export CDPATH" to avoid the problem in your script.
It's possible that user has some funky alias for "cd". Perhaps you could try making it do "/usr/bin/cd" (or whatever "cd" actually runs by default) instead.
Some people alias pwd to "echo $PWD". Also, the pwd command itself can either be a shell built-in or a program in /usr/bin. Do an "alias pwd" and "which pwd" on both that user and any user that works normally.
Try this:
sdir=$( cd $(dirname "$0") > /dev/null && pwd )
It's just a single line and will keep all special characters in the directory name intact. Remember that on Unix, only two characters are illegal in a file/dir name: 0-byte and / (forward slash). Especially, newlines are valid in a file name!

Resources