Closed renfrow closed 1 year ago
Hey @renfrow , I think it's because $1
should rather be \!:1
. $1
means $argv[1]
, \!
substitutes for the current invocation of the alias, so \!:1
is the first parameter to the alias itself.
/tmp> echo 'hi' > a@b.c
/tmp> alias cpr 'cp /tmp/a@b.c \!:1'
/tmp> cpr 2
/tmp> cat 2
hi
Also, I'd alias that as 'cp -T /whatever/@template.txt !:*' to allow myself more arguments to cp
, but that's just me.
Side note, I have tcsh 6.24.01 compiled from source.
/tmp> echo $version
tcsh 6.24.01 (Astron) 2022-05-12 (x86_64-unknown-linux) options wide,nls,dl,al,kan,sm,rh,color,filec
Or you could just not use an argument selector at all:
> alias cpr 'cp /tmp/a@b.c'
> echo hi > /tmp/a@b.c
> cpr 2
> cat 2
hi
Using an argument selector would let you ignore additional arguments, though, if that really was your goal:
> alias cpr 'cp /tmp/a@b.c \!^'
> cpr 3 4
> cat 3
hi
> cat 4
cat: 4: No such file or directory
Additionally, I'm unable to reproduce the error reported by @renfrow both directly on the command line and by using source
to get $1
to expand to something.
> alias cpr 'cp /tmp/a@b.c $1'
> echo hi > /tmp/a@b.c
> cpr 1
> cat 1
hi
> echo cpr 7 > oo
> source oo 12
cp: target '7' is not a directory
I perhaps was not clear: the name of the file is '@template.txt' (without the single quotes). That is to say, the first character of the filename is the at sign '@' (without the single quotes)(octal 100, decimal 64, hex 40). I am not attempting to use the (t)csh builtin command @.
What I would expect from this alias is that 'cpr newfile.txt' would be a copy of '@template.txt' named 'newfile.txt'. I copied this alias from another alias where the template file does not begin with '@' (octal 100, decimal 64, hex 40).
I work on both windows desktop, and linux via putty. On windows the '@' char sorts to the top of the folder. I sftp'd the template to the remote VPS linux box without considering that the '@' would throw a monkey wrench in the remotely copied alias (I very rarely use Powershell/cmd on windows). Until this error occured, I was not aware that '@' was a command. And had I known I would not have renamed the file as single quotes protected the '$' from being special, and I would have thought it would also protect the '@'. I hope I've made some sense :).
NOTE: you can type 'cp @template.txt newfile.txt' at a tcsh prompt and not get an error, it's in the alias(ing) that the problem occurs. NOTE2: version tcsh 6.21.00 (Astron) 2019-05-08 (x86_64-unknown-linux) options wide,nls,dl,al,kan,sm,rh,nd,color,filec
Okay, I now get what you're saying. I can't reproduce it on 6.24.01 on Ubuntu even with a bare @
as filename.
/tmp> echo 1 > @
/tmp> rm -f 2
/tmp> alias cpr 'cp @'
/tmp> cpr 2
/tmp> cat 2
1
I tried to build the 6.21 tag to see if it reproduces there, but I got a strange compile/link error and gave up.
Okay, I got 6.21 compiled and running, and I cannot reproduce.
tcsh-6.21> ./tcsh
tcsh-6.21> cd /tmp
/tmp> echo hi > @template
/tmp> alias cpr 'cp @template \!:1'
/tmp> cpr 2
/tmp> cat 2
hi
/tmp> echo $version
tcsh 6.21.00 (Astron) 2019-05-08 (x86_64-unknown-linux) options wide,nls,dl,al,kan,sm,rh,color,filec
(okay, let's try to do it like the pr...)
/tmp> alias cpr 'cp /tmp/@template $1'
/tmp> cpr 3
/tmp> cat 3
hi
/tmp> echo $version
tcsh 6.21.00 (Astron) 2019-05-08 (x86_64-unknown-linux) options wide,nls,dl,al,kan,sm,rh,color,filec
To my (somewhat limited knowledge) @
is only meaningful (i.e. it does the whole expression math thing) if it's the first token on a line, but your line starts with cpr
or cp
or whatever.
It seems we have the same config options enabled.
Maybe it's a Cygwin thing, but I don't have a Windows machine available right now to test.
I've tried with `\x{40}' but that doesn't seem to get interpreted during an alias.
Can you try with set echo
, maybe it gives more clues?
Or, call it quits and create /usr/local/bin/cpr
with the cp command. I can't seem to reproduce it on either 6.21 or 6.24.
I haven't been using cygwin, just drag-n-drop on windows.
OK, just redid the alias, from scratch, but, with an important change. The FULL alias was: alias cpr 'cp /where/ever/@template.txt $1 && chmod +w $1'
When I posted it, I removed the '&& chmod +w $1', thinking that was superfluous. It wasn't. I redid the alias without that part, and it worked, as everyone else's did. I tried replacing the '&&' with a ';', still got the error.
(I eventually did a bash script just so I could motor on, until I saw that you'd continued looking at this, and revisited it this morning.)
@renfrow the takeaway is that tcsh's aliases use \!:1
(or 2 or *
or $ or whatever), not the dollar-sign syntax. Your alias should work if you use the escaped exclamation point instead. $argv
is something you pass to a script/executable, aliases get substituded while the line is being read and they don't get argv.
Your alias caused cp
to error out because $1
was empty. Use set echo
to see what's actually executing.
@renfrow The other takeaway is that if you are reporting a bug or error, or just asking a question, please report exactly what you did, or if you don't want to report that, at least verify that what you are reporting is actually accurate.
This saves a lot of time for everybody.
Thanks.
alias cpr 'cp /where/ever/@template.txt $1'
Ditto for '.../\@template.txt...' Ditto for '.../\'@\'template.txt...' Ditto for '.../\'@\'template.txt...' Ditto for '.../'''@'''template.txt...' Ditto for '.../\\@template.txt...'