Executing an executable must be done using a path. Why? - unix

In the following:
Roberts-MacBook-Pro:Code robertnash$ mkdir Flag
Roberts-MacBook-Pro:Code robertnash$ cd Flag/
Roberts-MacBook-Pro:Flag robertnash$ swift package init --type executable
Roberts-MacBook-Pro:Flag robertnash$ swift build
Compile Swift Module 'Flag' (1 sources)
Linking ./.build/debug/Flag
In order to execute the executable, it must be a path, like so
Roberts-MacBook-Pro:Flag robertnash$ .build/debug/Flag
Hello, world!
If I go to where 'Flag' is located, the command cannot be run by simply typing 'Flag'.
Roberts-MacBook-Pro:Flag robertnash$ cd .build
Roberts-MacBook-Pro:.build robertnash$ cd debug
Roberts-MacBook-Pro:debug robertnash$ Flag
-bash: Flag: command not found
It must be a path, like so.
Roberts-MacBook-Pro:debug robertnash$ ./Flag
Why is that ?

If you run export PATH="$PATH:." then it will add the current working directory to your path and you won't need the ./ prefix. (Most (all?) shells accept just a trailing colon without the dot, but I find it's more explicit about what it does.)
This isn't present by default because it is a security risk: a malicious script could be named as something missing from your path, like nmap or even as a typo like sl, and placed in a directory in the hopes that you run it. Forcing you to prefix ./ is a good way of avoiding that.

Related

Run jq command in git-bash

jq command not found after adding jq executable
installing jq on git bash
My usecase is more similar with above shared references. I tried to execute a hook that needs to parse a json file. When hook gets executed it throws bash: jq:command not found error. So. I downloaded jq-win64.exe file and copied it to /usr/bin in Git folder. Then from git-bash I run export PATH=$PATH:"/C/Program Files/Git/usr/bin/jq-win64.exe" command and there is no error but when I checked jq --version command it still shows bash: jq:command not found error
Am I missing something? I even tried in windows cmd but is of no use. Hope someone can help me.
Thanks in advance!!!
PATH contains directories. That means what you should do:
Rename jq-win64.exe to jq.exe or just jq. (e.g. cp ~/Downloads/jq-win64.exe /usr/bin/jq).
You don't have to export your path, /usr/bin is already part of it.
If you didn't rename the file to jq (or jq.exe), then you would have to run it as jq-win64 in your console.
You could also put the binary into ~/bin folder, which should be part of PATH too. If it isn't, you can add it. Then you don't need to mess with your global binaries folder.

Recursively copy the *contents* of a directory

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

How to preserve file permissions with cmake "install directory" directive?

Prolog: I'm an idiot for missing this in the documentation
cmake-2.8.10.2
How do you make cmake preserve the original file permissions when installing a directory? For the project at hand, I'd like it to essentially copy some directories from my source tree to the install tree. To wit:
install(
DIRECTORY config runp
DESTINATION ${CMAKE_INSTALL_PREFIX}
PATTERN ".svn" EXCLUDE
PATTERN ".git" EXCLUDE
PATTERN "start_collection.snl" EXCLUDE
)
All works as expected -- except that executable scripts are getting copied in with incorrect file permissions. In fact, none of the original file permissions are preserved. Globally setting permissions using FILE_PERMISSIONS and DIRECTORY_PERMISSIONS is something I do not want to do, and frankly, would be a hack in this context.
In the shell-scripting world, I'd do something simple like this:
for i in config runp ; do
tar cf - $i | tar -C $CMAKE_INSTALL_PREFIX -xf -
done
Documentation suggests using USE_SOURCE_PERMISSIONS when calling install():
install(
DIRECTORY config runp
DESTINATION ${CMAKE_INSTALL_PREFIX}
USE_SOURCE_PERMISSIONS
PATTERN ".svn" EXCLUDE
PATTERN ".git" EXCLUDE
PATTERN "start_collection.snl" EXCLUDE
)
Alternatively, you can use install(PROGRAMS signature of this command. See docs for more info.

ANT uses wrong rm version

I want to execute ANT delete target, so that I can delete all files in the directory that mach some criteria:
<delete quiet="true">
<fileset dir="${java.io.tmpdir}" includes="soapirp*.log*"/>
</delete>
it does not work, I think it happens because ant is trying to invoke unix rm -f command which supposed to delete file without asking me to confirm the deletion, but this does not work, i tested it by running
rm - f filename
it still prompts me for the confirmation the only way I made it work by running:
/usr/bin/rm -f filename
then eveyting works as expected , I need to tell the ant to use the different version of rm I guess but how ??
ant uses the Java File API to delete files, not rm. Your problem must be elsewhere.
(and there must be no space between - and f).

`(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