Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game. |
| Notices |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
 |
GNU/Linux Basic Guide
This 255-page guide will provide you with the keys to understand the philosophy of free software, teach you how to use and handle it, and give you the tools required to move easily in the world of GNU/Linux. Many users and administrators will be taking their first steps with this GNU/Linux Basic guide and it will show you how to approach and solve the problems you encounter.
Click Here to receive this Complete Guide absolutely free. |
|
 |
|
06-22-2009, 03:27 AM
|
#16
|
|
LQ Newbie
Registered: Apr 2009
Location: China, Shanghai
Distribution: Fedora 7
Posts: 2
Rep:
|
a little modification
Quote:
Originally Posted by Disillusionist
Code:
source="./tmp/myfile"
dest=~/.Waste/$(echo $source|sed "s@^./@$PWD@"|sed "s@^/@@")
|
Disillusionist:
a little modifiation
Code:
source="./tmp/myfile"
dest=~/.Waste/$(echo $source|sed "s@^./@$PWD/@"|sed "s@^/@@")
|
|
|
|
09-07-2009, 02:34 PM
|
#17
|
|
Member
Registered: Jun 2004
Posts: 43
Rep:
|
Quote:
Originally Posted by Andy Alkaline
I'd like to be able to move the file into ~/.Waste/original/path
Using $PWD doesn't guarantee that. I need to have the absolute path of the file returned.
(a few minutes later)
Found it.
Bash equivalent for PHP realpath()
|
Unfortunately readlink is not on every bash system
|
|
|
1 members found this post helpful.
|
11-02-2009, 06:55 PM
|
#18
|
|
LQ Newbie
Registered: May 2009
Posts: 1
Rep:
|
Quote:
|
What is your concern with using $PWD? If concerned about someone exporting variables to an incorrect value, you could always use $(pwd) to set the value of PWD.
|
Because if you write scripts using absolute paths that are not depending on a) where the script starts from, or b) from cd'ing somewhere inside the script, $PWD is irrelevant.
ta0kira has it right: to return the absolute path of a filename that is originally given with a relative path:
for example you are at a bash prompt in /dir1/dir2/dir3/dir4
and the file is /dir1/dir2/file1
ABSOLUTE_DIR=$(dirname $(readlink -f ../../dir2/file1))
|
|
|
|
08-25-2010, 05:16 AM
|
#19
|
|
LQ Newbie
Registered: Jul 2009
Location: Singapore
Distribution: Gentoo, Kubuntu
Posts: 4
Rep:
|
A solution I found elsewhere...
|
|
|
|
08-25-2010, 10:50 AM
|
#20
|
|
LQ 5k Club
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian Squeeze (server), Slackware 13.37 (netbook), Slackware64 14.0 (desktop),
Posts: 8,357
|
Another solution is to use the external pwd command instead of the bash builtin. In the following illustration /home/c/Templates is a symlink to /home/c/d/Templates
Code:
c@CW9:~$ ls -l Templates
lrwxrwxrwx 1 c users 11 2010-06-07 11:43 Templates -> d/Template
c@CW9:~$ cd Templates
c@CW9:~/Templates$ pwd
/home/c/Templates
c@CW9:~/Templates$ echo $PWD
/home/c/Templates
c@CW9:~/Templates$ /bin/pwd
/home/c/d/Templates
|
|
|
1 members found this post helpful.
|
12-28-2010, 02:58 PM
|
#21
|
|
Member
Registered: Jun 2004
Location: Minnesota
Distribution: Slackware32-stable, Debian-wheezy-amd64, LFS 7.1
Posts: 258
Original Poster
Rep:
|
I didn't know readlink was nonstandard. Thanks to the suggestions, this is what I've come up with.
Code:
#!/bin/bash
# abspath.sh
# Find absolute path of file or symbolic link without using readlink
# December 28, 2010
function absp() {
local FILE=$1
local CWD=$(pwd)
# remove trailing slash
FILE=${FILE%/}
local FBN=`basename "$FILE"`
# Remove basename to get relative path
local RP="${FILE%$FBN}"
# change dir to relative path to run pwd
cd "$RP"
# Assign present working dir to $MOVETO; pwd returns the
# absolute path
AP=$(pwd)
# Append filename to abs path
APFN=$(pwd)/$FBN
# Change back to directory we started in
cd "$CWD"
# echo -e "\n\tAbsolute path:"
# echo -e "\t$AP"
# echo -e "\n\tAbsolute path to file:"
# echo -e "\t$APFN\n"
return 0
}
absp $1
echo -e "\n\tAbsolute path:"
echo -e "\t$AP"
echo -e "\n\tAbsolute path to file:"
echo -e "\t$APFN\n"
exit 0
|
|
|
|
12-28-2010, 03:53 PM
|
#22
|
|
Member
Registered: Jun 2004
Location: Minnesota
Distribution: Slackware32-stable, Debian-wheezy-amd64, LFS 7.1
Posts: 258
Original Poster
Rep:
|
I like this better:
Code:
#!/bin/bash
# abspath.sh 0.01
# Find absolute path of file or symbolic link without using readlink
# December 28, 2010
function absp() {
# Call this function by
# VAR=`absp <filename> ap|apfn>` # backticks required
# ap will return absolute path; apfn will return absolute path with filename
local FILE=$1
local CWD=$(pwd)
# remove trailing slash
FILE=${FILE%/}
local FBN=`basename "$FILE"`
# Remove basename to get relative path
local RP="${FILE%$FBN}"
# change dir to relative path to run pwd
cd "$RP"
# Assign present working dir to $MOVETO; pwd returns the
# absolute path
local AP=$(pwd)
# Append filename to abs path
local APFN=$(pwd)/$FBN
# Change back to directory we started in
cd "$CWD"
case $2 in
ap)
echo "$AP"
;;
apfn)
echo "$APFN"
;;
*)
echo "NULL";return 1;break
;;
esac
return 0
}
# absp function takes two parameters; file name and ap|apfn
# This method allows different variable names for AP or APFN throughout the program
ABSOLUTE_PATH=`absp $1 ap`
ABSOLUTE_FILE=`absp $1 apfn`
echo $ABSOLUTE_PATH
echo $ABSOLUTE_FILE
exit 0
|
|
|
|
01-24-2011, 02:50 AM
|
#23
|
|
Member
Registered: Jun 2004
Location: Minnesota
Distribution: Slackware32-stable, Debian-wheezy-amd64, LFS 7.1
Posts: 258
Original Poster
Rep:
|
I made another change. In the previous function I posted, it has to be called three times if the absolute path, absolute path with filename, and base filename are required. That can slow things down. This method may be slightly more memory intensive, but speeds up the process.
Code:
function gfp_info() {
local FILE=$1
# save pwd to cd back to it below
local CWD=$(pwd)
# remove trailing slash
FILE=${FILE%/}
# Get the basename of the file
local file_basename=`basename "$FILE"`
# Remove basename to get relative path
# Using bash's string function instead of calling
# dirname
local RP="${FILE%$file_basename}"
# change dir to relative path
cd "$RP"
# Assign present working dir to $fileap; pwd returns the
# absolute path
local fileap=$(pwd)
# Append base filename to absolute path
local ap_with_basename=$(pwd)/$file_basename
# Change back to directory we started in
cd "$CWD"
AP="${fileap}"
APFN="${ap_with_basename}"
FBN="${file_basename}"
return 0
}
# Initialize variables used in function so they can be used globally
AP=""
APFN=""
FBN=""
gfp_info "$FILENAME"
# The three variables above will now have value.
|
|
|
|
01-24-2011, 10:50 AM
|
#24
|
|
LQ 5k Club
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian Squeeze (server), Slackware 13.37 (netbook), Slackware64 14.0 (desktop),
Posts: 8,357
|
It could go a little faster if: - local CWD=$(pwd) was removed and cd "$CWD" was changed to cd -
- file_basename=`basename "$FILE"` was changed to file_basename="${FILE##*/}"
- fileap=$(pwd) was changed to fileap=$PWD
- ap_with_basename=$(pwd)/$file_basename was changed to ap_with_basename=$fileap/$file_basename or ap_with_basename=$PWD/$file_basename. In the latter case $fileap need not be used if suggestion 6 is implemented.
- AP=""
APFN=""
FBN=""
were removed; these variables are created as global variables by assigning values to them in the function.
- AP="${fileap}" were moved prior to cd "$CWD" in which case $fileap need not be used if suggestion 4, second option is implemented.
Incidentally ...
pwd does not return the absolute path if the path was reached via a symlink in which case pwd -P is needed:
Code:
c@CW8:~$ cd /tmp
c@CW8:/tmp$ mkdir foo
c@CW8:/tmp$ ln -s foo bar
c@CW8:/tmp$ cd bar
c@CW8:/tmp/bar$ pwd
/tmp/bar
c@CW8:/tmp/bar$ pwd -P
/tmp/foo
RP="${FILE%$file_basename}" does not generate a relative path; it extracts the directory component of the full path. A relative path is one that does not begin with "/". The same could be achieved by the common idiom RP=${FILE%/*} (the double quotes are not necessary on the RHS of an assignment "=". Strictly speaking these are not "bash string functions" but bash parameter expansions.
|
|
|
1 members found this post helpful.
|
01-24-2011, 10:51 AM
|
#25
|
|
LQ 5k Club
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian Squeeze (server), Slackware 13.37 (netbook), Slackware64 14.0 (desktop),
Posts: 8,357
|
Quote:
Originally Posted by catkin
Another solution is to use the external pwd command instead of the bash builtin.
|
That works but using the pwd builtin with the -P option is faster.
|
|
|
1 members found this post helpful.
|
01-25-2011, 03:39 PM
|
#26
|
|
Member
Registered: Jun 2004
Location: Minnesota
Distribution: Slackware32-stable, Debian-wheezy-amd64, LFS 7.1
Posts: 258
Original Poster
Rep:
|
I've made the changes to my script, with some exceptions.
cd "-" &>/dev/null
And when I was using rmw on a file in my present working directory, RP=${FILE%/*} would kick out an error. (No slash to find)
Thanks for the suggestions, catkin. Good stuff.
|
|
|
|
01-26-2011, 03:28 AM
|
#27
|
|
LQ 5k Club
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian Squeeze (server), Slackware 13.37 (netbook), Slackware64 14.0 (desktop),
Posts: 8,357
|
Quote:
Originally Posted by Andy Alkaline
And when I was using rmw on a file in my present working directory, RP=${FILE%/*} would kick out an error. (No slash to find)
|
Strange; it should silently do nothing as in
Code:
c@CW8:/tmp$ FILE=foo
c@CW8:/tmp$ var=${FILE%/*}
c@CW8:/tmp$ echo $var
foo
|
|
|
|
01-26-2011, 01:20 PM
|
#28
|
|
Member
Registered: Jun 2004
Location: Minnesota
Distribution: Slackware32-stable, Debian-wheezy-amd64, LFS 7.1
Posts: 258
Original Poster
Rep:
|
I was wrong about the slash, but the code you suggested assigns the basename, whereas I want everything except for the basename. Since I'm not good at explaining, allow me to illustrate:
Code:
# extracts the directory component of the full path
# local DC="${FILE%$file_basename}"
local DC="${FILE%/*}"
echo -e $c_1"FILE: $FILE"$c_reset
cd "$DC"
echo -e $c_1"DC: \"$DC\" pwd: - \"$(pwd -P)\" "$c_reset
# Assign present working dir to $fileap; pwd returns the
# absolute path
local fileap=$(pwd -P)
andy@pigeon:~/Documents$ rmw temp
FILE: temp
/home/andy/bin/rmw: line 451: cd: temp: Not a directory
DC: "temp" pwd: - "/home/andy/Documents"
`temp' -> `/home/andy/.Waste/files/temp.2011-01-26h13m11s43'
---
Code:
# extracts the directory component of the full path
local DC="${FILE%$file_basename}"
# local DC="${FILE%/*}"
echo -e $c_1"FILE: $FILE"$c_reset
cd "$DC"
echo -e $c_1"DC: \"$DC\" pwd: - \"$(pwd -P)\" "$c_reset
# Assign present working dir to $fileap; pwd returns the
# absolute path
local fileap=$(pwd -P)
andy@pigeon:~/Documents$ rmw temp
FILE: temp
DC: "" pwd: - "/home/andy/Documents"
`temp' -> `/home/andy/.Waste/files/temp.2011-01-26h13m14s23'
I've added an if clause around cd $DC
Code:
if [ $DC ]; then
cd "$DC"
fi
If in the same dir as the file, no need to tell cd to change to nothing and waste everyone's time.
Last edited by Andy Alkaline; 01-26-2011 at 01:26 PM.
Reason: Add modification
|
|
|
|
01-26-2011, 11:41 PM
|
#29
|
|
LQ 5k Club
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian Squeeze (server), Slackware 13.37 (netbook), Slackware64 14.0 (desktop),
Posts: 8,357
|
For the basename: basename=${fullpath##*/}. It looks like this at the command prompt:
Code:
c@CW8:/tmp$ fullpath=/etc/rsyncd.conf
c@CW8:/tmp$ basename=${fullpath##*/}
c@CW8:/tmp$ echo $basename
rsyncd.conf
|
|
|
|
01-27-2011, 09:37 AM
|
#30
|
|
Member
Registered: Jun 2004
Location: Minnesota
Distribution: Slackware32-stable, Debian-wheezy-amd64, LFS 7.1
Posts: 258
Original Poster
Rep:
|
Code:
function gfp_info() {
# Thanks to catkin for the massive improvements to this function
# http://www.linuxquestions.org/questions/user/catkin-444761/
local FILE=$1
# remove trailing slash
FILE=${FILE%/}
# Get the basename of the file
local file_basename="${FILE##*/}"
# extracts the directory component of the full path
local DC="${FILE%$file_basename}"
if [ $DC ]; then
cd "$DC"
fi
# Assign present working dir to $fileap; pwd returns the
# absolute path
local fileap=$(pwd -P)
# Append base filename to absolute path
local ap_with_basename=$fileap/$file_basename
# Change back to directory we started in
cd "-" &>/dev/null
AP="${fileap}"
APFN="${ap_with_basename}"
FBN="${file_basename}"
return 0
}
|
|
|
|
|
Tags
|
bash, bin, can, command substitution, console, link, mv, path, php, recycle, rm, scripts, sed, symbolic, trash  |
| Thread Tools |
Search this Thread |
|
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -5. The time now is 12:11 AM.
|
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|