LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Bash confusion about $1 (https://www.linuxquestions.org/questions/programming-9/bash-confusion-about-%241-402966/)

rose_bud4201 01-13-2006 12:59 PM

Bash confusion about $1
 
For some reason, I can do this:

Code:

[1044:lthurber@tdsccas01 ~]$alias s='head -n 1 $1'
[1045:lthurber@tdsccas01 ~]$ s testfile.txt
This is the first line of the file

And I can do this:
Code:

[1047:lthurber@tdsccas01 ~]$ alias ht='echo "Head: "; head -n 1 $1'
[1048:lthurber@tdsccas01 ~]$ ht testfile.txt
Head:
This is the first line of the file

But I can't do this:
Code:

[1052:lthurber@tdsccas01 ~]$ alias ht='echo "Head: "; head -n 1 $1;'
When I try running it, I get "Head:" printed out, then the script hangs 'til I hit Ctrl+C, at which point I get:
Code:

[1053:lthurber@tdsccas01 ~]$ ht testfile.txt
Head:
<<Ctrl+C here>>
bash: ./testfile.txt: Permission denied
[1054:lthurber@tdsccas01 ~]$

As far as I can tell it's the ; after the head command that does it. Since I'm aiming for something along the lines of alias ht='echo "Head: "; head -n 1 $1; echo -e "\nTail: "; tail -n 1 $1', this is a bit of a problem.
Is there a way to work around this? I'd love to be able to get the first & last line of a file in one little command.

Any help is appreciated, thanks!

Dave Kelly 01-13-2006 01:10 PM

SWAG.......
Check to see if 'testfile.txt' is executable.

Hko 01-13-2006 01:17 PM

I've tried your example aliases, and they work (except the one with the problem of course). This surprises me, because according to the bash man page you cannot use $1 in aliases. From "man bash":
Quote:

There is no mechanism for using arguments in the replacement text. If arguments are needed, a shell function should be used
I don't know how it's possible for it to work (sometimes), but I wouldn't count on it..

Create a script in your $PATH (e.g. /usr/local/bin) instead of an alias (or a function as the man page suggests). Use aliases only for simple one-liners.

rose_bud4201 01-13-2006 01:17 PM

Nope, definitely not executable. I don't want it to be, all I want to do is get the first line out of it.

I'm just confused why this happens:
[1027:lthurber@tdsccas01 ~]$ alias h1='head -n 1 $1'
[1028:lthurber@tdsccas01 ~]$ alias h2='head -n 1 $1;'
[1029:lthurber@tdsccas01 ~]$ h1 testfile.txt
This is the first line of the file
[1030:lthurber@tdsccas01 ~]$ h2 testfile.txt
<<Ctrl+C>>
bash: ./testfile.txt: Permission denied

*shrug* I'm sort of mystified. Also, apologies for naming the thread wrong; that's what happens when I continue to diagnose during the writing of the thread :-[

rose_bud4201 01-13-2006 01:20 PM

Quote:

Originally Posted by Hko
Create a script in your $PATH (e.g. /usr/local/bin) instead of an alias (or a function as the man page suggests). Use aliases only for simple one-liners.

Hmm..I guess I'll have to do it the script way then (I tend not to simply for fear of losing track of the scripts in the chaos that is my home directory).

Thanks!

Hko 01-13-2006 01:24 PM

Quote:

Originally Posted by rose_bud4201
I tend not to simply for fear of losing track of the scripts in the chaos that is my home directory

You could put it in /usr/local/bin instead.

rose_bud4201 01-13-2006 01:32 PM

Unfortunately, it's not my server =/ It's alright, I made the script and then aliased 'ht' to it ;)

gilead 01-13-2006 02:08 PM

$1 wasn't being used as an argument in the examples you were giving.

What was happening in the examples you gave was that the shell was expanding $1 as a shell variable, not an argument. Most likely if you type `echo $1` it is empty. When you used the alias, it ran the echo, but it tried to run the next part as `head -n 1 ;` - that is head with no input. If you then forced it to continue it ran the last part (the file testfile.txt) which is not executable and you got the error 'Permission denied'.

The man page recommends exactly what you ended up doing anyway - creating a script.

Just my 2c on what happened during the execution...

Hko 01-13-2006 03:49 PM

Quote:

Originally Posted by gilead
$1 wasn't being used as an argument in the examples you were giving.

What was happening in the examples you gave was that the shell was expanding $1 as a shell variable, not an argument. Most likely if you type `echo $1` it is empty. When you used the alias, it ran the echo, but it tried to run the next part as `head -n 1 ;` - that is head with no input.

Sounds true to me. But it does not explain why this does seem to work:
Code:

alias s='head -n 1 $1'
Anybody?

gilead 01-13-2006 05:06 PM

Yes it does. The steps are

1. You run `s somefile.txt`
2. The shell expands 's' to `head -n 1 $1`
3. The shell expands $1 to an empty string
4. The command that is run is head -n 1 somefile.txt

The $1 is treated as an environment variable, not an argument. Try typing `echo $1` and see what is returned.

Hko 01-14-2006 04:29 AM

Quote:

3. The shell expands $1 to an empty string
4. The command that is run is head -n 1 somefile.txt
Ah! That makes sense.
The filename is used by the (aliased) command because it's already there on the commmand line. Not because of expansion of "$1".
Thanks.

gilead 01-14-2006 04:54 AM

Glad it helped. It was the permission denied error that I recognised - I'd accidentally tried to run a non-executable file not long before I saw rose_bud4201's original post.


All times are GMT -5. The time now is 05:44 PM.