I want to start a process (from bash script) whose executable is inside current directory, in another directory $dir (nohup analog for windows cmd START /D). How to do such thing in bash?
If you want the process to execute from $dir, just do:
( cd $dir; ~-/cmd)
where cmd is the name of the executable in the current directory you wish to execute. The parentheses cause the two commands to run in a subshell so that your current shell does not change directory, and the ~- references the previous directory. Using ~- is not necessary if your current directory is in your PATH, and you may prefer to use a full path instead. Note that it is generally considered bad practice to put . in your PATH.
Related
I run windows command in particular directory and I need to pass files and subdirectories in this directory with full path. How to retrieve full path of current directory? What is analog of bash $PWD?
$pwd is indeed a valid command in PowerShell as well (if you're using PowerShell). $pwd in PowerShell is basically an alias for Get-Location - both of them will give you the full path of current directory.
In case you are using cmd, use cd (just cd without any parameters)
I have a c5 project with a directory C5PROJECTDIR it has a bin directory. Is there a way (without adding C5PROJECTDIR/bin to $PATH) to access commands from any other subdirectory of C5PROJECTDIR?
For example:
There is an x command located here: C5PROJECTDIR/bin/x.
I want to run this command from a bash script from C5PROJECTDIR/packages/some-other-dir.
UPDATE: The sub directory can be more or less deeper in the tree...
How can it be possible?
There are a few ways:
Use relative paths:
Essentially call the binary directly with its path, but relative to the current script. If your script is located in /home/user/foo/C5PROJECTDIR/packages/somedir/script, then you call the script relatively:
#!/usr/bin/env bash
../../bin/x
The problem with this method is maintainability. Imagine you want to move your script to /home/user/foo/C5PROJECTDIR/packages/scripts, then you would have to update all your scripts.
Use a shell variable:
Instead of relative paths, you can define a variable PROJECTHOME which contains the base value.
#!/usr/bin/env bash
PROJECTHOME=/home/user/foo/C5PROJECTDIR
$PROJECTHOME/bin/x
This generally solves most problems unless you move project location from /home/user/foo/C5PROJECTDIR to /home/user/random-dir. But this can be solved with a simple sed command that searches for the line /home/user/foo/C5PROJECTDIR and replaces it.
PATH variable only make things easier.
You able to run any commands with absolute path like /bin/echo or /home/jon/myscript. Relative path works as well ~/../../bin/ls.
Script have its own PATH variable, so you can add the desired location to PATH in your script if you like.
Apart from this you have to deal with permissions.
The user that have script executed by, must have execute permission on the x script.
To find and execute command:
find C5PROJECTDIR -type f -executable -name "x" -exec {} \;
Find's must be strict to match only one command else it will execute all that it fund. You cannot have script with the same name under C5PROJECTDIR in this case.
From security point of view. I do not recommend this, as anyone can put an executable file under C5PROJECTDIR with a name used in the script. things can go nasty.
My goal is to write an app that lets you quickly assign aliases to long directory paths and change to them. I wrote an app that manages them in a file in the user's appdata directory, but I can't find a way to change the directory of the shell I run the program in from my app. My goal is to have it work from git bash, cmd.exe, and powershell. I want something like this:
cd /c/vsts/some-long-project-name-reports
g -a reports
Now I have an alias 'reports' for that directory. What I want to do get to that directory next time I open a console is:
g reports
I'm using dotnet core, though looking through questions it seems like there isn't a way to do this at all. With Directory.SetCurrentDirectory(path); or Environment.CurrentDirectory = path; it changes the working directory of the g.exe process, but when it exits the shell goes back to it's working directory when I ran the command.
I've come up with a solution for git bash, I changed my g app to output the path instead and have this as go in my path:
OUTPUT="$(g $1)"
cd $OUTPUT
Then I just need to use . or source to run the script in the current shell:
. go reports
And batch file go.bat doesn't need the . or source to work:
for /F "tokens=*" %%i in ('g %1') do set OUTPUT=%%i
cd %OUTPUT%
I guess I'll have to live with typing the extra characters, but is there a similar way to do this with powershell?
Define a wrapper function in PowerShell (assuming that g.exe outputs the target path):
function g { Set-Location (g.exe $args) }
Generally, as eryksun points out in a comment, an executable - which by definition runs in a child process - cannot change its parent process' working directory.
Therefore, the only solution is to output the target directory's path and let the parent process change to it.
i have a small script that runs a jar file :
#!/bin/bash
prefix="foo";
name=`ls ${prefix}*.jar`;
echo $name;
java -jar $name prop1.properties prop2.properties
when i run it in the terminal using ./myscript.sh, it works fine and the jar file executes, but when i rename it in myscript.command and double click it, i have this error :
ls: foo*.jar : No such file or directory
I saw that apparently a .command file opens a terminal at the root directory, so I tried finding the directory containing myscript.command using that :
dir = 'find <dir> -maxdepth 1 -type d -name '*myDirContainingJar*' -print -quit'
cd $dir
but dir is just blank, any ideas ???
Opening a shell script from Finder on macOS (whether it has extension .command or is an extension-less executable shell script) makes the current user's home directory the current directory (as of macOS 10.12).
To explicitly change to the directory in which the script itself is located in a bash script, use:
cd -- "$(dirname -- "$BASH_SOURCE")"
In this invocation scenario, the following POSIX-compliant variation, which uses $0 in lieu of $BASH_SOURCE, would work too: cd -- "$(dirname -- "$0")"
Note:
Generally, if your script is invoked via a symlink and you want to change to the target's directory (the actual script file's directory as opposed to the directory in which the symlink is located), more work is needed - see this answer of mine.
When opening a script from Finder, however, this issue does not apply, because Finder itself resolves a symlink to its (ultimate) target and then invokes the target directly.
The problem with your script is that it runs with a different working directory than you tested it with. When you do ls something in a script, the script looks in the current working directory (where you cded last in case you're in a terminal), not in the directory the script is in. In general, when writing scripts like this you should use the full path of the file you're referring to or figure out the directory of the script and point to the file relative to that. One solution works in Bash, but it might not in the shell you're using.
I got Gnu Utilities that adds the command sed to windows, but to use it I have to type:
C:\ProgramFiles\GnuWin32\bin\sed.exe <args>
How do I shorten this to just sed <args>?
To run an executable without a full path, it needs to be either in the current directory, or in the PATH environment variable. In the CMD prompt, there are several ways to do this.
The first way is to put C:\ProgramFiles\GnuWin32\bin in your PATH variable, which makes every program in that directory available without a full path.
set "PATH=%path%;C:\ProgramFiles\GnuWin32\bin"
This updates PATH in the current command prompt. If you need to set it for other CMD windows, see How to persistently set a variable in Windows 7 from a batch file?
The second method is to have sed.exe in the current directory. The most obvious way to do that is to change directories.
cd C:\ProgramFiles\GnuWin32\bin
sed
Or you can copy it to your current directory.
copy C:\ProgramFiles\GnuWin32\bin\sed.exe .\
sed
(This works with sed.exe because it's a self-contained utility. Don't try this with a Windows application like excel.exe)
Finally, you can create a "redirect" somewhere in the current directory or the path.
>.\sed.bat echo C:\ProgramFiles\GnuWin32\bin\sed.exe %*
This creates a batch file in the current directory called sed.bat that calls the full sed.exe. You can drop this file into any directory in your PATH.
mklink .\sed.exe C:\ProgramFiles\GnuWin32\bin\sed.exe
This creates a symlink to the sed.exe in the current directory, much like a symlink in Unix or a shortcut in Windows.