Set expand_alias when shopt not available?
Asked Answered
G

1

1

I'm trying to use an alias in a shell script I'm writing, but it is not working.

The alias:

alias ts="awk '{ print strftime(\"[%Y-%m-%d %H:%M:%S]\"), \$0 }'"

When I run the script, I get the following error:

./copyTask.sh: ts: not found

Sooping around on the internet, it seems that I need to enable the expand_aliases shell option, but I don't have shopt installed... Is there any way I can enable alias expansion without using shopt or creating another rootfs image?

I'm using the ash shell. And awk is BusyBox v1.25.0 awk.

NOTE: The alias is an easy way to prepend a timestamp to a commmand:

$ echo "foo" | ts
[2005-06-23 11:52:32] foo

EDIT: as some people are having trouble understanding what I mean, this answer has an example.

Greenshank answered 16/11, 2017 at 13:54 Comment(6)
@Ignacio, can you elaborate?Greenshank
alias the command means then you need to add that in .bashrc file, not sure what you want to do?Hamon
@LethalProgrammer, I want to create a 'local' alias. That is, an alias that is valid only during the execution of my script. It seems that this does not work unless expand_alias is set...Greenshank
If you don't have shopt, your shell isn't bash. That happens, in practice, as if code is called with /bin/sh.Kirby
...though if your shell is a new enough bash, you might want to use the new printf %()T support for timestamp formatting internal to the shell itself.Kirby
(BTW, is this busybox's embedded ash, or an external one? Easy way to test is looking at whether your sh binary is either a symlink to, or has the same inode number as -- and thus is a hardlink to -- the busybox executable; if it is busybox ash, I might change the title to "Using aliases in a script with busybox sh").Kirby
K
3

Don't use aliases in scripts. A function does the same job better.

ts() { gawk '{ print strftime("[%Y-%m-%d %H:%M:%S]"), $0 }' "$@"; }
  • This works with any POSIX shell, including ones that don't support aliases at all.
  • This works with noninteractive shells without needing to enable alias support explicitly.
  • This can be extended in ways that aliases can't (you can put conditional logic inside functions; you can put arguments in non-tail positions in functions; etc).
  • In bash, functions can be exported to the environment: export -f ts will make the ts command available to subprocesses (where the shell they run is also bash).
Kirby answered 16/11, 2017 at 16:24 Comment(9)
Works perfectly on my host machine. However, the script I'm writing is for an embedded system, which has ashas its shell, and uses awk... When I run $ ts "foo" the result is awk: cmd. line:1: Unexpected tokenGreenshank
If awk '{ print strftime("[%Y-%m-%d %H:%M:%S]"), $0 }' foo gives the same error, then the shell (which is, after all, the subject of this question) is doing everything right.Kirby
BTW, when you ask a question where this is in-scope, you might consider specifying the specific version of awk your embedded system uses. I wouldn't be surprised if it were nawk or Busybox awk, but either way, details matter.Kirby
The command works normally, even when aliased. The issue is that if I try to create the alias inside a script, the alias isn't recognized, which I suspect is due to the lack of alias expansion.Greenshank
I'm using busybox awk. Thanks for the tip. Will update the description.Greenshank
Please run with sh -x yourscript, and provide the log line for the awk invocation it's attempting. (As an aside, I've confirmed that busybox awk does provide strftime -- whereas MacOS's awk does not, for example).Kirby
See gist.github.com/charles-dyfis-net/…, with logs of my own test (and the script I used, showing this shell function working perfectly with busybox 1.21.1).Kirby
@ Charles, here's my testGreenshank
Let us continue this discussion in chat.Kirby

© 2022 - 2024 — McMap. All rights reserved.