LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
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


Reply
  Search this Thread
Old 10-31-2008, 07:02 PM   #1
Andy Alt
Member
 
Registered: Jun 2004
Location: Minnesota, USA
Distribution: Slackware64-stable, Manjaro, Debian64 stable
Posts: 528

Rep: Reputation: 167Reputation: 167
bash script - return full path and filename


I'm attempting to improve a bash script, ReMove to Waste. It moves files into ~/.Waste and prepends the present working directory to the destination folder under ~/.Waste.

I'd like to have it moved to the same path from where the file or folder originate.
For instance, if I'm in my home directory, and delete a file within it called "temp," it will move it to ~/.Waste/home/andy/temp

So that is indeed where the file is supposed to go, but it's basing it on my PWD at the time.

I'd like to return the full path of the file name. But whatever PWD I'm in, the best I can get is "./temp"

basename and dirname are the opposite of what I need.
I tried ${FILE%} but that also returns "./temp"

I've been googling for over an hour, but getting nowhere.

Thanks, in advance.
 
Old 10-31-2008, 07:08 PM   #2
jailbait
LQ Guru
 
Registered: Feb 2003
Location: Virginia, USA
Distribution: Debian 12
Posts: 8,340

Rep: Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550
Use $PWD as a prefix to the file name.

---------------------
Steve Stites
 
Old 10-31-2008, 07:28 PM   #3
Andy Alt
Member
 
Registered: Jun 2004
Location: Minnesota, USA
Distribution: Slackware64-stable, Manjaro, Debian64 stable
Posts: 528

Original Poster
Rep: Reputation: 167Reputation: 167
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()
 
Old 11-02-2008, 05:04 AM   #4
nishamathew1980
Member
 
Registered: Oct 2008
Posts: 37

Rep: Reputation: 16
Wow ... That's something new I learnt today. Thanks for pointing me to the article - http://andy.wordpress.com/2008/05/09...-php-realpath/



Linux Archive

Last edited by nishamathew1980; 11-09-2008 at 04:49 AM.
 
Old 11-04-2008, 01:19 AM   #5
Andy Alt
Member
 
Registered: Jun 2004
Location: Minnesota, USA
Distribution: Slackware64-stable, Manjaro, Debian64 stable
Posts: 528

Original Poster
Rep: Reputation: 167Reputation: 167
Quote:
Originally Posted by nishamathew1980 View Post
Wow ... That's something new I learnt today. Thanks for pointing me to the article - http://andy.wordpress.com/2008/05/09...-php-realpath/

I noticed using it in a reMoval script can be a little hazardous. It won't move the symbolic link, it goes after the source file instead. Be careful!
 
Old 11-04-2008, 01:50 AM   #6
Disillusionist
Senior Member
 
Registered: Aug 2004
Location: England
Distribution: Ubuntu
Posts: 1,039

Rep: Reputation: 98
Code:
source="./tmp/myfile"
dest=~/.Waste/$(echo $source|sed "s@^./@$PWD@"|sed "s@^/@@")
 
Old 06-19-2009, 02:29 PM   #7
Andy Alt
Member
 
Registered: Jun 2004
Location: Minnesota, USA
Distribution: Slackware64-stable, Manjaro, Debian64 stable
Posts: 528

Original Poster
Rep: Reputation: 167Reputation: 167
Linux console recycle bin

Disillusionist, thanks, but unfortunately, I don't know what your code does. Regular expressions confuse me greatly (though I'm now starting to realize how useful sed can be and that I need to learn how to use it), and I saw PWD in there; using the present working directory was something I was trying to avoid.

Here's the script so far, for anyone interested. The -u option will undo the last operation performed. This is the version currently in the subversion repo at http://sourceforge.net/projects/rmw

I won't be doing anything more with it for a few weeks or month, but if anyone has any suggestions for improvements, I'll most likely implement them at some point.

Code:
#!/bin/sh
# rmw - ReMove to Waste
# Author: Andy Alt ( https://sourceforge.net/projects/rmw/ )
# May 30, 2009
# License: GPL
# Description: ReMove to Waste, rmw, is a bash script.
# It functions as a Linux/Unix console recycle bin when
# reMoving files with rm. ReMove to Waste will move files
# to a Waste folder or "Trash can," and it will prepend
# the time and date to files when reMoving them. It keeps a
# "history" to easily copy files back to their previous location.
# 
# WARNING: Use this script at your own risk.

# Change this to set the location of the rmw configuration directory
RMWCONF=${HOME}/.rmw

debug=1
# Other variables can be found in the file rmwrc (which will be created
# after this script has been run once) in your rmw config directory

displayver() {
	echo -e "\nReMove to Waste $VERSION\n"
}

displayhelp() {

echo usage: -i / interactive
echo -v / be verbose
echo -u / undo-last ReMove
echo -f / force, no prompting
 } 

VERSION=0.97-svn-2009May30

if [ $# -eq 0 ]; then
	echo "No options passed"
	exit 1
fi

mvargs="-"

while getopts ":ivfuh" Option
do

case $Option in
    i     ) mvargs=$mvargs"i";;
    v     ) mvargs=$mvargs"v";;
#    v     ) verbosity=1;;
    f     ) mvargs=$mvargs"f";;
#    v     ) echo $VERSION;;
    u	) doundo=1;;
    h	) displayhelp;;
#    *     ) echo "Unimplemented option chosen.";;   # DEFAULT
  esac
done

shift $(($OPTIND - 1))

if [ $mvargs == "-" ]; then
	mvargs=""
fi

	if [ $doundo ]; then
		source ${RMWCONF}/undofile-last
		exit 0
	fi

#if [ $debug = 1 ]; then
	
#fi



# Create config dir if it doesn't exist
if [ ! -d ${RMWCONF} ]; then
	echo ""
	mkdir -pv ${RMWCONF}
	
	if [ ! -d ${RMWCONF} ]; then
		echo "Unable to read/write configuration directory!*"
		exit 1
	fi
fi

# Create configuration file if it doesn't exist
#
#
if [ ! -e ${RMWCONF}/rmwrc ]; then
echo ""
echo "Creating rmw configuration file ${RMWCONF}/rmwrc"
#cat > ${RMWCONF}/rmwrc << "EOF"
cat > ${RMWCONF}/rmwrc << "EOF"
# The following two lines added by rmw installation script
WASTE=${HOME}/.Waste
# After running rmw x times, disk usage of Waste directory will
# be displayed. Use 0 to disable
showdu=10
#
# Number of undo files to keep
num_undofiles=20
#
# Use verbosity even if it's not passed on the command line
# 0 to disable
verbosity=1
EOF
fi

# Read in variables from configuration file
source ${RMWCONF}/rmwrc
#


if [ ! $num_undofiles ]; then
cat >> ${RMWCONF}/rmwrc << "EOF"
# Number of undo files to keep
num_undofiles=20
EOF
num_undofiles=20
fi

if [ ! $verbosity ]; then
cat >> ${RMWCONF}/rmwrc << "EOF"
#
# Use verbosity even if it's not passed on the command line
# 0 to disable
verbosity=1
EOF
verbosity=1
fi

if [ $verbosity = 1 ]; then
	mvargs=$mvargs" -v"
fi

if [ -e ${RMWCONF}/UndoFilesCounter ]; then
	
	undofile_count=`cat ${RMWCONF}/UndoFilesCounter`
	
	else

	echo 0 > ${RMWCONF}/UndoFilesCounter
	undofile_count=1
	
	fi

if [ $undofile_count -gt $num_undofiles ]; then

	undofile_count=1

	else
	
	((undofile_count++))

fi

echo $undofile_count > ${RMWCONF}/UndoFilesCounter

UNDO_FILE=${RMWCONF}/undofile-${undofile_count}

# BUG - This will overwrite an UNDO file even if rmw
# is being executed without filenames to ReMove
#
echo "" > $UNDO_FILE

displayver


# The mv command has a --suffix option, but I chose to
# prepend the time and date. That keeps the file extension
# intact, and thus, if desired later, more easily opened 
# using a file manager
#
# date --help for more details
#
PREPENDSTR=`date +%Fh%Hm%Ms%S`

	for FILE in "${@}" ; do

	if [ -e "${FILE}" ]; then
		filecounter=1

# -h tests whether or not the file is a symlink.
# See ChangeLog (May 25, 2009) for more details.
# readlink will ReMove the source file, so if the 
# file is a symlink, the readlink/abs path section
# will be skipped.

		if [ ! -h "${FILE}" ]; then

# readlink finds the absolute path of the file being reMoved.
# I use the absolute path (instead of present working directory)
# so we'll know where the file was originally located.
		ABSFILEPATH=`readlink -f "${FILE}"`
		ABSPATH=$(dirname "${ABSFILEPATH}")
		DEST=${WASTE}${ABSPATH}
		BNAME=`basename "${ABSFILEPATH}"`

# I should probably change the $DEST var to $DESTDIR
		if [ ! -d "${DEST}" ]; then
			mkdir -vp "${DEST}"
		fi

# The three lines below write to an undo file
#
echo "if [ ! -d \"${ABSPATH}\" ]; then" >> ${UNDO_FILE}
echo "mkdir -vp \"${ABSPATH}\"" >> ${UNDO_FILE}

echo "fi" >> ${UNDO_FILE}


			if [ ! -e "${DEST}"/"${BNAME}" ]; then
				mv $mvargs "${ABSFILEPATH}" "${DEST}"/"${BNAME}"
				echo mv $mvargs \""${DEST}"/"${BNAME}"\" \""${ABSFILEPATH}"\" >> $UNDO_FILE

				
			else
				mv $mvargs "${ABSFILEPATH}" "${DEST}"/"${PREPENDSTR}"_"${BNAME}"
				echo mv $mvargs \""${DEST}"/"${PREPENDSTR}"_"${BNAME}"\" \""${ABSFILEPATH}"\" >> $UNDO_FILE

			fi

# If statement commented, I don't think it's necessary
# anymore.
#
#		if [ ! -n "$mvargs" ]; then
			echo "ReMoved ${FILE}"
#		fi

# This is what happens to symlinks

# Removal of symlinks are not yet added to the undo file
		else

			mkdir -pv "${WASTE}""${PWD}"
			mv -iv "${FILE}" "${WASTE}""${PWD}"

		fi


	fi
	


	done

if [ ! -e ${RMWCONF}/timesrun ]; then
	echo 1 > ${RMWCONF}/timesrun
fi


if [ $showdu -ne 0 ];then

	timesrun=`cat ${RMWCONF}/timesrun`

	if [[ $timesrun -ge $showdu ]];
		then echo 1 > ${RMWCONF}/timesrun
		echo ""
		echo "Disk usage for Waste folder:"
		du -sh $WASTE

		elif [ $showdu -gt 0 ];then

		((timesrun++))
		echo $timesrun > ${RMWCONF}/timesrun
	fi 
fi


# Can we figure out how to empty the Waste automatically 
# if directory usage exceeds x number of bytes?
#
#echo !`du -s $WASTE`!
#if [ `du -s $WASTE` gt 64000 ]; then
#	echo "Deleting Waste"
#echo "greater than 64000"
#	/bin/rm -ir $WASTE
#fi

echo ""

# If any files were ReMoved, copy the Undo file to undofile-last
# for use with the --undo-last option
# If we didn't ReMove any files, this would copy an old undo file
# to undofile-last, some of those files may not exist anymore, or we
# we wouldn't want them restored.
# Using the filecounter var to make sure that doesn't happen
#


if [[ -e $UNDO_FILE && $filecounter ]]; then
	cp -v --remove-destination $UNDO_FILE ${RMWCONF}/undofile-last
	echo ""
fi


exit 0


# end script
 
Old 06-19-2009, 04:37 PM   #8
Disillusionist
Senior Member
 
Registered: Aug 2004
Location: England
Distribution: Ubuntu
Posts: 1,039

Rep: Reputation: 98
Quote:
Originally Posted by Andy Alkaline View Post
Disillusionist, thanks, but unfortunately, I don't know what your code does. Regular expressions confuse me greatly (though I'm now starting to realize how useful sed can be and that I need to learn how to use it), and I saw PWD in there; using the present working directory was something I was trying to avoid.
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.

The important part of the code I suggested, passed the value of $source through two sed statements.:
Code:
echo $source|sed "s@^./@$PWD@"|sed "s@^/@@"
The first sed statement looked was to replace any instances of ./ at the start of the variable with $PWD

The second sed statement removes the leading / character
 
Old 06-19-2009, 06:00 PM   #9
Andy Alt
Member
 
Registered: Jun 2004
Location: Minnesota, USA
Distribution: Slackware64-stable, Manjaro, Debian64 stable
Posts: 528

Original Poster
Rep: Reputation: 167Reputation: 167
Quote:
Originally Posted by Disillusionist View Post
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.
My only concern is that I want rmw'ed files to go to ~/.Waste/original/path. In most cases $PWD would be fine, but if I'm removing files from /tmp or ~/Documents while my pwd is /mnt/cdrom, for example, they wouldn't be quite as easy to "restore" later.

I'm still using $PWD for symlinks. I'm using 'readlink' to determine absolute paths, and it always returns the source of the symlink, which I don't want.

Last edited by Andy Alt; 06-19-2009 at 06:03 PM. Reason: addendum
 
Old 06-20-2009, 03:24 AM   #10
Disillusionist
Senior Member
 
Registered: Aug 2004
Location: England
Distribution: Ubuntu
Posts: 1,039

Rep: Reputation: 98
The sed statement would only use PWD where the source file begins with ./

Any files that begin with ./ are by definition starting from the current working directory.

EDIT:

Your script (downloaded from sourceforge) needs to run as #!/bin/bash on my machine (although I suspect this is the same on others) as source is a shell builtin for bash, but doesn't appear to be for traditional bourne shell. -- I am using Jaunty (Ubuntu 9.04)

Last edited by Disillusionist; 06-20-2009 at 04:01 AM.
 
1 members found this post helpful.
Old 06-20-2009, 03:06 PM   #11
Andy Alt
Member
 
Registered: Jun 2004
Location: Minnesota, USA
Distribution: Slackware64-stable, Manjaro, Debian64 stable
Posts: 528

Original Poster
Rep: Reputation: 167Reputation: 167
Thanks, I made the change and issued a new file release (made some other changes too).

On Slackware, which is my primary system, /bin/sh is a symlink to /bin/bash.
 
Old 06-20-2009, 03:51 PM   #12
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Try this (where $file is e.g. ./temp):
Code:
echo "$( readlink -f "$( dirname "$file" )" )/$( basename "$file" )"
Kevin Barry

Last edited by ta0kira; 06-20-2009 at 04:03 PM.
 
1 members found this post helpful.
Old 06-21-2009, 04:34 AM   #13
Disillusionist
Senior Member
 
Registered: Aug 2004
Location: England
Distribution: Ubuntu
Posts: 1,039

Rep: Reputation: 98
Quote:
Originally Posted by Andy Alkaline View Post
Thanks, I made the change and issued a new file release (made some other changes too).

On Slackware, which is my primary system, /bin/sh is a symlink to /bin/bash.
New package is missing an install.sh file

It would also be nice to see an uninstall.sh file to simplify removal.

EDIT:
As rm is linked to rmw, you need rmw to cater for all the options that rm can use, especially rm -rf

Last edited by Disillusionist; 06-21-2009 at 04:56 AM.
 
1 members found this post helpful.
Old 06-21-2009, 05:51 AM   #14
vonbiber
Member
 
Registered: Apr 2009
Distribution: slackware 14.1 64-bit, slackware 14.2 64-bit, SystemRescueCD
Posts: 533

Rep: Reputation: 129Reputation: 129
Quote:
Originally Posted by Andy Alkaline View Post
I'm attempting to improve a bash script, ReMove to Waste. It moves files into ~/.Waste and prepends the present working directory to the destination folder under ~/.Waste.

I'd like to have it moved to the same path from where the file or folder originate.
For instance, if I'm in my home directory, and delete a file within it called "temp," it will move it to ~/.Waste/home/andy/temp

So that is indeed where the file is supposed to go, but it's basing it on my PWD at the time.

I'd like to return the full path of the file name. But whatever PWD I'm in, the best I can get is "./temp"

basename and dirname are the opposite of what I need.
I tried ${FILE%} but that also returns "./temp"

I've been googling for over an hour, but getting nowhere.

Thanks, in advance.
ok, if I understood correctly you have a bash script
(say, move2waste.sh) that is
in your $PATH, perhaps in /usr/local/bin, and when
you

move2waste.sh some_file

where some_file is in a certain directory /some/path

you want some_file to be moved to /some/path/.Waste

(provided you have the right permissions in /some/path)

I would go like that (I'll skip the permissions verifications,
the number of arguments, etc.)

#!/bin/sh

# here you loop for each argument entered,
# verifying that the file exists, etc.
# say the file to be processed is in $filename
# $filename is a basename (no preceding directories:
# you invoke the script in the directory where
# you want to move files)

CWD=$PWD
# create .Waste directory if it doesn't already exist
mkdir -p $CWD/.Waste

mv $filename $CWD/.Waste

##################################

if you want to invoke the script move2waste.sh with
arguments such as
/absolute/path/to/filename
or
relativepath/to/filename

you should, when you process these arguments, retrieve the
the part before the filename
(e.g., argument=/some/path/filename
p=${argument%/*})
then figure out if it's a relative or absolute path:
if it starts with '/' it's absolute, otherwise relative
('.', '[a-zA-Z0-9]', ...)
if it's absolute you set CWD to that: CWD=$p
if it's relative:
if it starts with './' you remove that (p=$(echo $p | sed 's?^\./??'),
if it starts with '../', you get the name of the directory above ...
then you set CWD to $CWD/$p
 
1 members found this post helpful.
Old 06-21-2009, 01:40 PM   #15
Andy Alt
Member
 
Registered: Jun 2004
Location: Minnesota, USA
Distribution: Slackware64-stable, Manjaro, Debian64 stable
Posts: 528

Original Poster
Rep: Reputation: 167Reputation: 167
I've been using readlink for a few months now, so I'm no longer in need of methods to use absolute paths.

Quote:
Originally Posted by Disillusionist View Post
New package is missing an install.sh file

It would also be nice to see an uninstall.sh file to simplify removal.

EDIT:
As rm is linked to rmw, you need rmw to cater for all the options that rm can use, especially rm -rf
Thanks yet again.

I issued another release, and included the install-sh file which 'configure' requires.
I also edited it, and the configure script to change #!/bin/sh to #!/bin/bash

I added support for the -rf option. It'll be a while before I add support for all the other other options 'rm' has. I'm recovering from some pain issues which limits the amount of time I'm able to spend at the computer. Know of any good speech recog programs?

As for an uninstall.sh, I don't know how to do that while accounting for what users might set for a prefix install dir using 'configure'. The install-sh file is just copied from my automake directory when I create the Makefile.in.

For a workaround, I added more information to the INSTALL file about where files are being copied to. I also added an UNINSTALL file with more instructions. Additionally, I created a .deb package and an .rpm package while logged into my Kubuntu 9.04 partition and those two files are available for download on the sourceforge project page. I used checkinstall to create the packages.

Thanks for all your suggestions.
 
  


Reply

Tags
bash, bin, can, command substitution, console, link, mv, path, php, recycle, rm, scripts, sed, symbolic, trash



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
ls - Do not list full path only filename baddah Linux - General 12 06-17-2013 12:21 AM
bash - return home path babag Programming 2 06-01-2008 04:59 PM
Getting the first part of a filename in a BASH script trevelluk Programming 3 02-15-2005 01:06 AM
php mail script return path richard22 Linux - Software 1 08-22-2003 04:10 AM
bash script - incrementing a filename in a script tslinux Programming 10 08-05-2003 11:58 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:14 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration