keep hard link connection after erasing a file - linux

I try to achieve something that I imagined very simple, but which is finally harder than expected.
I have a folder : source/. I have a second one : target/. I create a file test.jar in my first folder. Then, I want this file to appear and be executable in my second folder. I see 3 options :
manually copy/paste my file. It works but... I don't want to do it each time I update my file.
symbolic link. It works, but if I execute the jar file, the context is source/ and not target/ like I would like.
hard link. That's exactly what I need, but the issue is that test.jar is not modified, but generated. This means that after erasing source/test.jar, target.test.jar still references the old file... Is it possible to force the 2 files to have always the same value ?
Thanks for your help !
EDIT : For now, I solved the problem by adding a line to copy my file from source/ to target/ inside a script that I will execute anyway after generating the jar. I think that what I wanted to do is actually impossible. It would need a new kind of linking which links the content of 2 files given their pathname and not their inode...

Don't create a soft link of the file. Create a soft link of the entire folder.
Something like
ln -s {whatever path}/source/ {whatever path}/target
Then the folder target/ is a folder-link to the first folder and context should be the same.
You can also try using git (locally) and checkout source/ to folder target.

You can try creating an executable shell script named test.jar in the target directory and make it call the path/source/test.jar passing forwarding all the parameters. Something like:
#!/bin/bash
path/source/test.jar "$#"

Related

linux source a symbolic link

I have a bash script which i want to call from any directory, but i don't want to add the directory it is in to PATH as it is filled with lots of other scripts which will just clutter.
The script in question manipulates environment variables, so i have to source it.
I tried creating an alias
alias aliastoscript="/path/to/script"
source aliastoscript #This does not work says no such file
I also can't copy the script itself to a different location as it depends on the directory structure and other scripts in the directory.
So i tried a symlink to a location already in path:
ln -s /path/to/script /directory/already/in/path/myscript
But this does not work either:
source myscript #says no such file exists
Can anyone suggest how i achieve this? And why does the symlink approach not work?
If it makes any difference, i am using a zsh shell on ubuntu 14.04
EDIT:
The answer given below works, but i also wanted to know why the symlink approach was not working.
Here is the sequence of commands
ln -s /path/to/script /directory/already/in/path/myscript
#Now there is a symlink called myscript in a directory which is in PATH
source myscript arg1 #This throws an error saying no such file myscript,
#but it is not supposed to happen because myscript resides in a directory which is in PATH
EDIT 2:
I just figured what i was doing wrong, the symlink i created, i had used relative paths, totally stupid of me, using absolute paths it worked like a charm.
Try replacing:
alias aliastoscript="/path/to/script"
with:
export aliastoscript="/path/to/script"
You have a $ missing in front of the variable name.
source $aliastoscript
You do not need soft link for the source. The complete file name should work. Better is
source /path/to/script

How to use command zip in linux that folder have short path?

I used command zip in linux (RedHat), this is my command:
zip -r /home/username/folder/compress/zip.zip /home/username/folder/compressed/*
Then, i open file zip.zip, i see architecture as path folder compress.
I want to in folder zip only consist list file *.txt
Because i used this command in script crontab hence i can't use command cd to path folder before run command zip
Please help me
I skimmed the zip man page and this is what I have found. There is not an option archive files relative to a different directory. The closest I have found is zip -j which removes the entire path and stores the files directly in the zip rather than sub directories. I do not know what happens in the case of file name conflicts such as if /home/username/folder/compressed/a.txt and /home/username/folder/compressed/subdir/a.txt both exist. If this is not a problem for you, you can use this option, but I am concerned because you did specify the -r option indicating that you expect zip to traverse sub folders.
I also thought of the possibility that your script could somehow call zip with a different working directory, but I took a look at this unix stack exchange page and it looks like their options use cd.
I have to admit I do not understand why you cannot use cd and I am very curious about it. You said something about using crontab, but I have never heard of anything wrong with changing directories in a crontab script.
I used option -j in command zip
zip -jr /home/username/folder/compress/zip.zip /home/username/folder/compressed/*
and i was yet settled this problem, thanks

SVN Pre-commit Symbolic Link Path in Perl

In my workplace, there's one Perl script that runs on a Unix machine every time someone tries to check-in a file to the SVN repo for any of the 10-20 projects.
The way it works is that each project has its own "Hooks" folder with a file called "pre-commit" which SVN automatically executes when someone check-in something. Except the "pre-commit" file is actually a symbolic link to the one central Perl script common to all projects just so that if a change needs to be made to the Perl script it doesn't need to be done for every project.
So my problem is this: I need to put a text file in each of these projects' "hooks" directory, each one containing some settings specific to that project. So there will be 10-20 settings files (one per project) each in their respective "hooks" directory.
The problem is that I need to open these text files in the Perl script and read from them but I'm having issues letting Perl know where to find it. I tried using the $0 parameter which is supposed to tell me where the script is being executed from but because it's a symbolic link it just says "Not a directory" and the script terminates. I need to get the path of the "hooks" directory so that I can find the text file.
The SVN pre-commit script is supposed to be invoked with the path to the repository as its first argument. Inside a Perl script, that argument should be available as $ARGV[0]. You should be able to build the path to the corresponding hooks directory or to a file inside that directory by simply appending to the repository path, like this:
$repopath = $ARGV[0];
$hookspath = $repopath . "/hooks";
$myfilepath = $hookspath . "/myfile";
although for maximum portability it would be cleaner to use the pathname-manipulation functions in the File::Spec module to do this.
If this approach doesn't work then you'll have to explain more about how your Perl script gets invoked. For instance, if your pre-commit script is really a shell script wrapper that eventually invokes perl then perhaps it's not passing the pre-commit arguments along properly.
Showing us your current code that's failing would be a good thing too.

how to copy between folders and parent folder without complete path

This is a basic question but I am struggling to find a decent solution. This is hindering my script from automation.
I have the following path.
/home/hassan/Dyna/ProjectSimulation
in project simulation I have 3 folders
friction time force
like
/home/hassan/Dyna/ProjectSimulation/friction
Now I have a file friction1.txt in this friction folder and I want to copy it to ProjectSimulation.
is it possible to avoid complete path and just one step down?
Also if I have to copy this friction1.txt to folder force, is there anyway to avoid the complete path.
I mean I have a subroutine but this is path dependent , whenever I run it , I have to run in the same folder and then copy my results so I can run only one instance of my simulation.
Experts please guide me.
PS: This is part of a 600 lines shell.
This comes across as so basic that I must have misunderstood something in your question.
If you want to refer to a parent directory, .. is the way to do that. So, if you want to copy friction1.txt to two places you just do
cp friction1.txt ..
cp friction1.txt ../force
All you need to take care of is making sure that CWD is
/home/hassan/Dyna/ProjectSimulation/friction
so that the references point at the right place.
You can temprarily change the current directory to ProjectSimulation, copy the file (cp friction/friction1.txt .), then change the path back to the original (so the rest of the script works as before)
Alternatively, you can use dirname to get he name of the parent directory and use that.
Change to the root dir of your known directory structure. Then do the copy operations with relative paths. Then change back to your dir where you came from.
Your friends are:
cd
cd -
or better:
pushd
popd
(see man bash)
I.e.
pushd /home/hassan/Dyna/ProjectSimulation
cp friction/friction1.txt .
cp friction/friction1.txt force
popd

Can you use tar to apply a patch to an existing web application?

Patches are frequently released for my CMS system. I want to be able to extract the tar file containing the patched files for the latest version directly over the full version on my development system. When I extract a tar file it puts it into a folder with the name of the tar file. That leaves me to manually copy each file over to the main directory. Is there a way to force the tar to extract the files into the current directory and overwrite any files that have the same filenames? Any directories that already exist should not be overwritten, but merged...
Is this possible? If so, what is the command?
Check out the --strip-components (or --strippath) argument to tar, might be what you're looking for.
EDIT: you might want to throw --keep-newer into the mix, so any locally modified files aren't overwritten. And I would suggest testing new releases on a development server, then using rsync or subversion to carry over the changes.
I tried getting --strip-components to work and, while I didn't try that hard, I didn't get it working. It kept flattening the directory structure. In searching, I came across the following command that seems to do exactly what I want:
pax -r -f patch.tar -s'/patch///'
It's not tar, but hey, it works... Replace the words "patch" with whatever your tar file name is.
The option '--strip-components' allows you to trim parts of the embedded filenames. With that it is possible to do what you want.
For more help check out http://www.gnu.org/software/tar/manual/html_section/transform.html
I have just done:
tar -xzf patch.tar.gz
And it overwrites all the files that the patch contains.
I.e., if the patch was created for the contents of the app folder, I would extract it there. Results would be like this:
tar.gz contains: oldfolder/someoldfile.txt, oldfolder/newfolder/newfile.txt
before app looks like:
app/oldfolder/someoldfile.txt
Afterwards, app looks like
app/oldfolder/someoldfile.txt
oldfolder/newfolder/newfile.txt
And the "someoldfile.txt" is actually updated to what was in the tar.gz
Maybe this doesn't work with regular tar, only tar.gz. But I doubt it. I think it should work for everything, as long as user has write permissions.

Resources