Something like this should do what you want:
for cmd in cat head tail; do
cmdLoc=$(type $cmd | awk '{print $3}')
eval "
$cmd() {
for fn in \"\$@\"; do
source-highlight --failsafe --out-format=esc -o STDOUT -i \"\$fn\" |
$cmdLoc -
done
}
"
done
You can condense it like this:
for cmd in cat head tail; do
cmdLoc=$(type $cmd |& awk '{print $3}')
eval "$cmd() { for fn in \"\$@\"; do source-highlight --failsafe --out-format=esc -o STDOUT -i \"\$fn\" | $cmdLoc - ; done }"
done
Example
With the above in a shell script, called tst_ccmds.bash
.
#!/bin/bash
for cmd in cat head tail; do
cmdLoc=$(type $cmd |& awk '{print $3}')
eval "$cmd() { for fn in \"\$@\"; do source-highlight --failsafe --out-format=esc -o STDOUT -i \"\$fn\" | $cmdLoc - ; done }"
done
type cat
type head
type tail
When I run this, I get the functions set as you'd asked for:
$ ./tst_ccmds.bash
cat ()
{
for fn in "$@";
do
source-highlight --failsafe --out-format=esc -o STDOUT -i "$fn" 2> /dev/null | /bin/cat - ;
done
}
head is a function
head ()
{
for fn in "$@";
do
source-highlight --failsafe --out-format=esc -o STDOUT -i "$fn" 2> /dev/null | /usr/bin/head - ;
done
}
tail is a function
tail ()
{
for fn in "$@";
do
source-highlight --failsafe --out-format=esc -o STDOUT -i "$fn" 2> /dev/null | /usr/bin/tail -;
done
}
In action
When I use these functions in my shell (source ./tst_ccmds.bash
) they work as follows:
cat
head
tail
plain text
What's the trick?
The biggest trick, and I would call it more of a hack, is the use of a dash (-
) as an argument to cat
, head
, and tail
through a pipe which forces them to output the content that came from source-highlight
through STDIN of the pipe. This bit:
...STDOUT -i "$fn" | /usr/bin/head - ....
The other trick is using the --failsafe
option of source-highlight
:
--failsafe
if no language definition is found for the input, it is simply
copied to the output
This means that if a language definition is not found, it acts like cat
, simply copying its input to the standard output.
Note about aliases
This function will fail if any of head
,tail
or cat
are aliases because the result of the type
call will not point to the executable. If you need to use this function with an alias (for example, if you want to use less
which requires the -R
flag to colorize) you will have to delete the alias and add the aliased command separately:
less(){
for fn in "$@"; do
source-highlight --failsafe --out-format=esc -o STDOUT -i "$fn" |
/usr/bin/less -R || /usr/bin/less -R "$fn"; done
}
Best Answer
msgattrib
display colors only if executed from real terminal. You can useunbuffer
command that's part ofexpect
to makemsgattrib
think that it's executed from real terminal and then use-r
option to handle ANSI escapes inless
:You can do that in any command that produce colors (ANSI escapes codes) based on existance of tty.