My Perl app receives relative paths to files and arguments and then converts them to absolute paths. I had been using Cwd::abs_path($fileName) just fine, but now I need to support symbolic links and I find that abs_path will give me the absolute path to the original file.
What I need is an alternative to Cwd::abs_path that when given a relative path to a symlink will convert it to an absolute path to that same symlink. Any recommendations?
Example:
/originals/myfile1
/links/myfile1link -> /originals/myfile1
> cd /links
> perl converter.pl /myfile1link
> output: /links/myfile1link
File::Spec->rel2abs does not do any system checks, so it won't resolve symlinks.
Related
I'm trying to get the absolute path to a file provided as a Windows path in Cygwin, respectively Msys (Git Bash) perl. I would like solutions that also work when the supplied path is a "native" Cygwin/MSys path.
I tried using Cwd::abs_path, but that seems subtly broken. Here is a test:
user#MYPC MINGW64 /f/Temp
$ perl
use Cwd;
print Cwd::abs_path("F:\\") . "\n";
print Cwd::abs_path("F:\\test.txt") . "\n";
print Cwd::abs_path("..\\test.txt") . "\n";
/f
/f/Temp/F:/test.txt
/f/Temp/../test.txt
Directories work, relative paths "work" but don't give the result I'd expect (i.e. .. is not eliminated), but when I add a filename to an absolute path the result is wrong. I had hoped that Cwd would do the path translation for me.
I need to later extract parts of the path (using the functions from File::Spec) and also want open the file. To continue working with the extracted part the path should be native to the perl version used. I want to avoid using cygpath, since I'd like the script to also work with ActivePerl, which understands Windows paths only. I could of course add some ifs to only call cygpath for the unix-y perls.
You do not have an absolute path. msys and cygwin are unix emulation environments, and in unix, absolute paths start with /. F:\ is a valid relative path and file name in unix.
Linux$ touch 'F:\'
Linux$ ls
F:\
In cygwin, /cygdrive/f/ refers to your F:. You can use the command-line utility cygpath to convert between native and Windows paths.
cygwin$ cygpath -w /cygdrive/c/
C:\
cygwin$ cygpath -u 'C:\'
/cygdrive/c/
msys should also have a way of accessing the Windows drive through its virtual unix file system.
How to find if debug information contains relative paths or absolute paths?
I am trying to Outputting annotated source (opannotate) using the following link.
http://oprofile.sourceforge.net/doc/opannotate.html
I would like to know about it in order to give the following options along with opannotate.
--base-dirs / -b [paths]/
Comma-separated list of path prefixes. This can be used to point OProfile to a different location for source files when the debug information specifies an absolute path on your system for the source that does not exist. The prefix is stripped from the debug source file paths, then searched in the search dirs specified by --search-dirs.
--search-dirs / -d [paths]
Comma-separated list of paths to search for source files. This is useful to find source files when the debug information only contains relative paths.
Thanks.
If the C_FLAGS during compilation contain the -g parameter, then all the paths of individual source files are included in the .debug_info section in the resulting binary executable.
The following command will dump to the console, a complete list of all the paths to various .c source files that are present in the binary built with debug-info.
$ readelf --debug-dump=info <binary-executable> | grep "\.c" | awk '{print $8}'
To search for the path of a particular source-file within the debug-info of the binary, one can modify the grep "\.c" to grep "<filename>" as appropriate.
For more details, checkout this excellent article on debug-info in binaries.
I am trying to use diffstrings.py from Three20 on my iPhone project, and I can't find the proper format for the path arguments (as in "Usage: diffstrings.py [options] path1 path2 ...").
For example, when I run the script in my Xcode project directory like this
~/py/diffstrings.py -b
it analyzes just the main.m and finds 0 strings to localize,
then it diffs against existing fr.lproj and others, and finds that thes contain "obsolete strings".
Can anyone post examples of successful comand line invocations of diffstrings.py, for options -b, -d and -m?
Taking a quick look at the code here http://github.com/facebook/three20/blob/master/diffstrings.py I see that if you don't specify any command line options, it assumes you mean the directory wherever the script lives in. So the option is to either copy .py file to where your .m files are, or simple use the command
~py/diffstrings.py -b .
That is, give the current directory (.) as the path argument.
In my Perl code, I need to copy a directory from one location to another on the same host excluding some files/patterns (e.g. *.log, ./myDir/abc.cl).
What would be the optimum way of doing this in Perl across all the platforms?
On Windows, xcopy is one such solution. On unix platforms, is there a way to do this in Perl?
I think you're looking for rsync. It's not Perl, but it's going to work a lot better than anything you make in Perl:
% rsync --exclude='*.log' --exclude='./myDir/abc.cl' SOURCE DEST
If you have a bunch of patterns, you can put those all in a file:
*.log
./myDir/abc.cl
Now ignore all the patterns in a file:
% rsync --exclude-from=do_not_sync.txt SOURCE DEST
I'd use File::Find, and step over each file, but instead of calling File::Copy's copy() on each file, first test to see if it matches the pattern, and then next if it does.
On *nix, you can use native tar command, with -exclude options. Then after creating the tar file, you can bring it over to your destination to untar it.
I am using the system command in MATLAB as follows (with the current directory being 'scripts'):
[status, result] = system('cd ..\\TxtInOut')
However, invoking the system command does not seem to work. It returns status = 0 and result = ''.
Any suggestions?
If you want to change directories, you should use the CD command. The argument can be either a full path or relative path:
cd('c:\matlab\toolbox'); %# Full path to a directory
cd('scripts'); %# Move to a subdirectory "scripts"
cd('..\TxtInOut'); %# Move up one level, then to directory "TxtInOut"
If you want information about a directory, you should use the DIR command. DIR will return an m-by-1 structure of information for a directory, where m is the number of files and folders in the directory. Again, the argument can be either a full path or relative path:
data = dir('c:\matlab\toolbox'); %# Data for a full path to a directory
data = dir('scripts'); %# Data for a subdirectory "scripts"
NOTE: When working on different platforms (i.e. Windows or UNIX), you will have to pay attention to whether you use the file separator \ or /. You can get the file separator for your platform using the function FILESEP. You can also build your file paths using the function FULLFILE.
Any command executed by "system" is external to MATLAB. A command shell is generated, executes your request, and then returns the result. The 0 result indicates successful completion: the command shell changed its current directory as requested and then returned. (Command shells use non-zero to indicate an error, because there are usually many more ways that a program can fail than succeed.) Unfortunately that only affects the command shell's current directory - see gnovice's answer for how to actually change the directory.
you can use cd, dir, ls, etc directly in matlab without call system functions.
You can also use the underlying operating system commands by preceding them by an exclamation sign.
For instance:
!dir will show you the current directory contents in Windows
!pwd will show you the current directory in Linux/Mac
But calling cd does not change the current directory!