Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Redirecting output, can I get actual name of file? 3

Status
Not open for further replies.

cptk

Technical User
Mar 18, 2003
305
US
Say I'm executing from the cmd line...

myprogram > RDfile

Is there a way to reference the actual redirected file name 'RDfile' in the ksh script?

Built-in shell variables like $* or $@ don't include any of the tokens right of the ">" cmd.

What about referencing the file descriptor ... how? What I need is the actual file name because I need to avoid this file in my script.
...thanks!
 
Hi

Let us start with an example :
Code:
[gray]#!/bin/sh[/gray]

[navy]log[/navy][teal]=[/teal][green][i]'sh.log'[/i][/green]
date [teal]>>[/teal] [green][i]"$log"[/i][/green]

[b]if[/b] [teal][[/teal] -t [purple]1[/purple] [teal]];[/teal] [b]then[/b]
  echo [green][i]'output is a terminal'[/i][/green] [teal]>>[/teal] [green][i]"$log"[/i][/green]
[b]else[/b]
  echo [green][i]'output is redirected'[/i][/green] [teal]>>[/teal] [green][i]"$log"[/i][/green]
fi

echo -n [green][i]'this will appear in '[/i][/green]

readlink [green][i]"/proc/$$/fd/1"[/i][/green]
Code:
[blue]master #[/blue] ./sh.sh
this will appear in /dev/pts/13

[blue]master #[/blue] ./sh.sh > out.txt
Code:
Thu Nov  5 18:40:57 EET 2009
output is a terminal
Thu Nov  5 18:41:09 EET 2009
output is redirected
Code:
this will appear in /home/master/tmp/out.txt
So the [tt]test[/tt], [tt][[/tt] or [tt][[[/tt] built-in's -t operator will tell if the output is a terminal. The process' FD ( file descriptor ) 1 ( STDOUT ) is a symlink to the actual file/device. The /proc/ directory's structure may vary from system to system.

I hope I understood you correctly.

Feherke.
 
Hi

I forgot one thing. On Unix do not search for [tt]readlink[/tt], you probably have none. Will have to extract it from [tt]ls[/tt] output or something. I used it for readability.

Feherke.
 
Feherke - thanks for replying ...

I didn't make myself clear - the redirected file is user-defined, thus it's never known ahead of time. Anyway, yes I am using the -t test, but what I found that looks promising is the utility 'lsof'. By using the pid=`echo $$` shell variable with the following:

tmp=`lsof - p $pid -a -d 1` ### -a=and, -d file descr.
FD=${tmp##*/} ## removes pattern from left, returns file name
 
Hi

cptk said:
I didn't make myself clear
No, you did. I didn't.

Because that is what my example does : outputs the name of where it outputs :
[ul]
[li]if outputs goes to a terminal, says 'this will appear in /dev/pts/pseudoterminal_number'[/li]
[li]if outputs goes to file out.txt, says 'this will appear in /path/to/out.txt'[/li]
[li]if outputs goes to file who's name you will dream this night, says 'this will appear in /path/to/whatever you will dream this night'[/li]
[/ul]
So it does quite the same thing as your code. But probably your is more portable.

( Maybe I should not use that log file. It is just to have a fixed destination where [tt]if[/tt]'s both branches output and is not affected by further redirection. )


Feherke.
 
I like feherke's solution better because it's much faster (doing the same thing). The lsof command can take a while to run some times.

Also, the path /prod/$$/fd/1 works for Linux. For Solaris you'll use /proc/$$/path/1. You'll have to try it for other *nixes.

I'll give feherke's reply a star. Good stuff.

 
Thanks guys ...

lsof is not a working as orig. thought - the expected pattern is not always consistent (on my system), thus I can't successfuilly always pattern-remove the leading chars to get at the trailing file name.

Sammy - I'm exploring your solaris idea of /proc/$$/path/1,
but I'm still not seeing the day of light. What utility would I use to "translate" this path to the actual user-supplied redirected file name??
 
Interesting stuff guys!

cptk, if you do an ls -l /proc/$$/path/1 it lists it as a symbolic link with the real path at the end of the output line, so ls -l /proc/$$/path/1 | awk '{print $NF}' should give you what you want?

Annihilannic.
 
Hi

Annihilannic said:
ls -l /proc/$$/path/1 | awk '{print $NF}' should give you what you want?
Supposing the output was not redirected to a file with whitespace characters in its name. Personally I would prefer this ( hoping that nobody will redirect to a file with " -> " in its name ) :
Code:
ls -l "/proc/$$/path/1" | awk -F ' -> ' '{print $NF}'
But let me continue with another potentially useless suggestion ( or useful if [tt]find[/tt] on Solaris handles -printf and understands [tt]%l[/tt] as "Object of symbolic link" ) :
Code:
find "/proc/$$/path/" -name '1' -printf '%l\n'


Feherke.
 
Thanks guys so far, but still not working ...
my path:

/proc/$$ contains the following:
[No View Set]:betta: /proc/19845 >ls -lA
total 9215
-rw------- 1 cpver users 4685824 Nov 5 22:06 as
-r-------- 1 cpver users 152 Nov 5 22:06 auxv
-r-------- 1 cpver users 32 Nov 5 22:06 cred
--w------- 1 cpver users 0 Nov 5 22:06 ctl
lr-x------ 1 cpver users 0 Nov 5 22:06 cwd ->
dr-x------ 2 cpver users 8208 Nov 5 22:06 fd
-r--r--r-- 1 cpver users 120 Nov 5 22:06 lpsinfo
-r-------- 1 cpver users 912 Nov 5 22:06 lstatus
-r--r--r-- 1 cpver users 536 Nov 5 22:06 lusage
dr-xr-xr-x 3 cpver users 48 Nov 5 22:06 lwp
-r-------- 1 cpver users 2688 Nov 5 22:06 map
dr-x------ 2 cpver users 544 Nov 5 22:06 object
-r-------- 1 cpver users 3424 Nov 5 22:06 pagedata
-r--r--r-- 1 cpver users 336 Nov 5 22:06 psinfo
-r-------- 1 cpver users 2688 Nov 5 22:06 rmap
lr-x------ 1 cpver users 0 Nov 5 22:06 root ->
-r-------- 1 cpver users 1472 Nov 5 22:06 sigact
-r-------- 1 cpver users 1232 Nov 5 22:06 status
-r--r--r-- 1 cpver users 256 Nov 5 22:06 usage
-r-------- 1 cpver users 0 Nov 5 22:06 watch
-r-------- 1 cpver users 4256 Nov 5 22:06 xmap


"path" is not an available dir, so 1st choice was to look at "fd" which yields:
c--------- 1 cpver tty 24, 7 Nov 5 22:06 0
--w------- 1 cpver users 0 Nov 5 22:06 1
c--------- 1 cpver tty 24, 7 Nov 5 22:06 2

... but the contents for "1" has retricted permission.

So, back up at the /proc/19845 dir level ...
- I recursively grep'ed for the redirected file name with no luck (I'm temporary using a large "sleep" value in my script so the pid stays open).
- the other files are pretty much binary files (less each file yields nothing of any worth).
- the linked files (cwd & root) lead to normal dir files.

So my issue is still the same: where can I find the name of the redirected file.
 
Actually, I get this direct struct /proc/$$/fd in either case ...
 
Yes, true about white-space evilness feherke, although I try my very best to avoid that unless it's in my MP3 collection. ;-)

What version of Solaris are we talking here, cptk? Perhaps /proc/$$/path only appeared in version 10...

Annihilannic.
 
I'm on Solaris 9 ...

BTW, the reason why I orig. fell away from the idea of using lsof is because when I run lsof from a VOB directory, the lsof output doesn't list the redirected file name like it does when I run from a non-VOB directory ... hmmmm
 
VOB? non-VOB? Can we see examples of the differing output for those two situations, whatever they are?

Normally something like this should do it:

Code:
OUTFILE=$(lsof -p $$ | awk '$4=="1w" {print $NF}')

Again, this will not accommodate white-space evilness, but let's tackle the simple case first.

Annihilannic.
 
Sorry Annihilannic, my bad - I took liberty on what's a VOB - it's Clearcase's version controlled files (Versioned Object Base).

Also, let me clarify with respect to the effects of a VOB file. It's not where I excute script from, it's where I'm directing the 'RDFILE' file that's an issue - if I run the script like this:

cpsgw > RDFILE, and I'm excuting from a non-VOB directory, all is good when using the lsof utility (the RDFILE will be created in the current non-VOB working dir). But, if I run script like this:
cpsgw > /{VOB dir}/RDFILE, the lsof doesn't provide me with what I need.

Examples of excuting lsof -p -a -d 1 using:

a.) cpsgw > RDFILE:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
cpsgw 25588 cpver 1w VREG 297,30 0 1610702705
/export/home/cpver/RDFILE

b.) cpsgw > /{VOB dir}/RDFILE
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
cpsgw 25605 cpver 1w VREG 299,212 0
/opt/ctis/adapt/ZHU /opt/Ccase/Vobs2/Ctis/ZHU.vbs)

I did cd'd to this dir (/opt/Ccase/Vobs2/Ctis/ZHU.vbs) and it's nothing more than clearcase-related files [which I did grep for the redirected file RDFILE with no luck]

Also, the dir /opt/ctis/adapt/ZHU is not where I redirected the 'RDFILE' - it's actually two more dirs down from /ZHU, so I couldn't even attempt locate file by date if I wanted to because I would know the the redirected file's dir path.

... and this is where I'm stuck. I've asked our system admin people about this issue with no great leads. He did suggest to look into Perl's arsenal of commands, which I did, again with no success.
 
There must be something weird about your directory structure because I couldn't reproduce that behaviour. Is /opt/ctis/adapt/ZHU the filesystem the destination file is actually on? Are there symbolic links somewhere in that destination path or something?

Annihilannic.
 
Annihilannic - thanks for responding - it's been a while since I addressed this issues ... I've moved on from this issue, as we all need to do eventually, but the geek in me would still however like to find a solution to this ...

Soooooo .....
No, /opt/ctis/adapt/ZHU is not the final file system of the redirected file, but it's close. In this example, it's two more dir's down from here ...

And, nope, there's no soft links of any kind in this dir pointing to my RDFILE dir.

As I said previously, there was a a lot of info. in this dir: /opt/Ccase/Vobs2/Ctis/ZHU.vbs , but nothing stood-out that was blatantly obvious.


I think I'm going to re-ask / mention this to our Sys admin - especially about the ZHU.vbs dir. If the answer is indeed in there, it's very cryptic ...
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top