I have a logo which I want to print/echo using bash in console, through scripts, but I can't even paste here properly(looks good inside .txt file):
___ _____ _ _ _____ _ _ ___
| _| / ___| | | || ___| \ | | |_ |
| | \ `--.| |_| || |__ | \| | | |
| | `--. \ _ || __|| . | | |
| | /\__/ / | | || |___| |\ | | |
| |_ \____/\_| |_/\____/\_| \_/ _| |
|___| |___|
How I can do that properly and make it colour without 3rd party extensions?
Also, is it possible to print it from the file?
You may use tput:
tput setaf 2; cat logo.txt
2 is the color code here (red). These are the available codes:
Value Color
0 Black
1 Red
2 Green
3 Yellow
4 Blue
5 Magenta
6 Cyan
7 White
8 Not used
9 Reset to default color
Related
Currently I have this kind of output format:
{ echo "$(figlet buddhi)"; echo "$(figlet lw)"; }
_ _ _ _ _
| |__ _ _ __| | __| | |__ (_)
| '_ \| | | |/ _` |/ _` | '_ \| |
| |_) | |_| | (_| | (_| | | | | |
|_.__/ \__,_|\__,_|\__,_|_| |_|_|
_
| |_ __
| \ \ /\ / /
| |\ V V /
|_| \_/\_/
And I would like to have this output format:
figlet buddhi lw
_ _ _ _ _ _
| |__ _ _ __| | __| | |__ (_) | |_ __
| '_ \| | | |/ _` |/ _` | '_ \| | | \ \ /\ / /
| |_) | |_| | (_| | (_| | | | | | | |\ V V /
|_.__/ \__,_|\__,_|\__,_|_| |_|_| |_| \_/\_/
The reason is: I would like to color each name (buddhi, lw) with a different color. But, retain the format of a continuous string, or at maximum space-separated, as above.
Example:
#COMMANDS CREATED INSIDE /ETC/BASH.BASHRC FILE
# USING ANSI COLORS
RED="\e[31m"
ORANGE="\e[33m"
BLUE="\e[94m"
GREEN="\e[92m"
STOP="\e[0m"
printf "${GREEN}"
printf "=================================\n"
printf "${ORANGE}"
figlet -f standard "Buddhi"
printf "${BLUE}"
figlet -f small "LW"
printf "${GREEN}"
printf "=================================\n"
printf "${STOP}"
Store the lines of each word in arrays, output both the arrays line by line. As the first line of "Buddhi" seems to be one character shorter, I stored the longest line length of the first word in a variable, and used the %-s format to pad each line.
#! /bin/bash
RED="\e[31m"
ORANGE="\e[33m"
BLUE="\e[94m"
GREEN="\e[92m"
STOP="\e[0m"
mapfile -t left < <(figlet -f standard "Buddhi")
mapfile -t right < <(figlet -f small "LW")
maxlength=0
for line in "${left[#]}" ; do
if (( ${#line} > maxlength )) ; then
maxlength=${#line}
fi
done
printf "${GREEN}"
printf "=================================\n"
for ((i=0; i<=${#left[#]}; ++i)) ; do
printf "${ORANGE}%-${maxlength}s ${GREEN}%s\n" "${left[i]}" "${right[i]}"
done
printf "${GREEN}"
printf "=================================\n"
printf "${STOP}"
If you need a shorter version:
printf "$GREEN=================================\n"
{ figlet Buddhi; echo 'EOF'; figlet LW; } | awk 'NF==1&&$1=="EOF" {noskip=1; next; } noskip==0 { f[++c]=$0; next; } { printf "%s%s%s%s\n","'"$ORANGE"'",f[++k],"'"$BLUE"'",$0;}'
printf "$GREEN=================================\n"
tput sgr0
I would recommend to use tput for setting the color as not every terminal will know your escape sequences
The guys who invented shell also invented awk for shell to call to manipulate text. Those escape sequences don't change colors on my terminal, they just show up as-is (fortunately so you can see where the script is puting them):
$ cat tst.sh
#!/usr/bin/env bash
awk '
BEGIN {
red = "\\e[31m"
orange = "\\e[33m"
blue = "\\e[94m"
green = "\\e[92m"
stop = "\\e[0m"
}
{
val[(NR==FNR),FNR] = $0
}
NR == FNR {
wid = length($0)
maxWid = ( wid > maxWid ? wid : maxWid )
}
END {
for ( lineNr=1; lineNr<=FNR; lineNr++ ) {
printf "%s%-*s%s%s%s\n", orange, maxWid, val[1,lineNr], blue, val[0,lineNr], stop
}
}
' <(cat Buddhi) <(cat LW)
$ ./tst.sh
\e[33m _ _ _ _ _ \e[94m _\e[0m
\e[33m| |__ _ _ __| | __| | |__ (_)\e[94m| |_ __\e[0m
\e[33m| '_ \| | | |/ _` |/ _` | '_ \| |\e[94m| \ \ /\ / /\e[0m
\e[33m| |_) | |_| | (_| | (_| | | | | |\e[94m| |\ V V /\e[0m
\e[33m|_.__/ \__,_|\__,_|\__,_|_| |_|_|\e[94m|_| \_/\_/\e[0m
Since I don't have figlet, I ran the above on these files:
$ head Buddhi LW
==> Buddhi <==
_ _ _ _ _
| |__ _ _ __| | __| | |__ (_)
| '_ \| | | |/ _` |/ _` | '_ \| |
| |_) | |_| | (_| | (_| | | | | |
|_.__/ \__,_|\__,_|\__,_|_| |_|_|
==> LW <==
_
| |_ __
| \ \ /\ / /
| |\ V V /
|_| \_/\_/
Just change the last line of the script from:
' <(cat Buddhi) <(cat LW)
to
' <(figlet Buddhi) <(figlet LW)
to use actual figlet output.
the above assumes you only have 2 figlet output strings to concatenate and that both sets of output are the same length, it's easy tweaks if either of those assumptions is wrong.
In lieu of figlet I'll use the following as my inputs:
$ cat buddhi
_ _ _ _ _
| |__ _ _ __| | __| | |__ (_)
| '_ \| | | |/ _` |/ _` | '_ \| |
| |_) | |_| | (_| | (_| | | | | |
|_.__/ \__,_|\__,_|\__,_|_| |_|_|
$ cat lw
_
| |_ __
| \ \ /\ / /
| |\ V V /
|_| \_/\_/
Assuming figlet generates the same number of output lines for each input string, we can use paste (# as a delimiter) and a while/read loop to generate the desired output:
printf "${GREEN}"
printf "============================\n"
maxwidth=$(awk '{max=length($0) > max ? length($0) : max}END{print max}' buddhi)
while IFS='#' read -r col1 col2
do
printf "${ORANGE}%-*s ${BLUE}%s\n" "${maxwidth}" "${col1}" "${col2}"
done < <(paste -d"#" buddhi lw)
printf "${GREEN}"
printf "============================\n"
This generates:
Expanding to 3 input streams:
printf "${GREEN}"
printf "============================\n"
max1=$(awk '{max=length($0) > max ? length($0) : max}END{print max}' buddhi)
max2=$(awk '{max=length($0) > max ? length($0) : max}END{print max}' lw)
while IFS='#' read -r col1 col2 col3
do
printf "${ORANGE}%-*s ${BLUE}%-*s ${RED}%s\n" "${max1}" "${col1}" "${max2}" "${col2}" "${col3}"
done < <(paste -d"#" buddhi lw buddhi)
printf "${GREEN}"
printf "============================\n"
This generates:
Using coordinates
#!/bin/bash
RED='\e[31m'
GRN='\e[32m'
XY(){ printf "\e[$2;${1}H$3"; }
mapfile -t frst < <(figlet -f standard "Buddhi")
mapfile -t scnd < <(figlet -f small "LW")
XY 1 1 "$GRN==============================================="; y=2
for line in "${frst[#]}"; { XY 0 $y "$RED$line"; ((y++)); }; y=2
for line in "${scnd[#]}"; { XY 35 $y "$GRN$line"; ((y++)); }
XY 1 8 "$GRN==============================================="
More examples here, here and here
i dont see why it isnt working.
if you could help me with this it would be greatly appreciated.
i run the file and it just exits out, as if the code is missing.
cls
echo //========================================//
echo \\ --- --- ---------- ---------- \\
echo // | \ | | | | | | //
echo \\ | \ \ | | -- -- -- -- \\
echo // | |\ \| | | | | | //
echo \\ | | \ | | | | | \\
echo // |__| \____| |__| |__| //
echo \\========================================\\
echo press any key to begin
pause
You need to escape the pipes | with a carret (^|).
However you should store ascii art in a txt file and use type my_banner.txt in order to display it. This is easier ...
(Shell Script) Set value of numbers from current time
Im trying to make a shell script to take the output from the current time (HH:MM) and assign a variable (font) to each number 0-9. This essentially is a clock, which I need to run in realtime (changes when the time changes). for example if I run this command:
date +"%T"
I will get an output (results may vary):
12:30:27
How can I make it so instead it will output this (without the "seconds")
_ ____ _____ ___
/ |___ \ _ |___ / / _ \
| | __) | (_) |_ \| | | |
| |/ __/ _ ___) | |_| |
|_|_____| (_) |____/ \___/
The only way I can think of achieving this is by assigning the numbers individually with the font being used. The link to the font i am using is:
http://patorjk.com/software/taag/#p=display&f=Standard&t=12%20%3A%2030
Is there anyway I can output the time (in realtime) using numbers like this?
To show a realtime ASCII art clock, use
watch 'date "+%H:%M" | figlet'
to save the current time in a variable, use
myVariable="$(date "+%H:%M" | figlet)"
As long as your cursor is not at the bottom of the screen, and you are in a terminal emulator that supports these cursor motions:
#!/bin/sh
f() { echo -n "\\033[$1D\\033[1B"; }
_c=" _$(f 2)(_)$(f 2)_$(f 2)(_)$(f 1) "
_0=" ___$(f 4)/ _ \\ $(f 7)| | | |$(f 7)| |_| |$(f 6)\\___/ "
_1=" _$(f 2)/ |$(f 3)| |$(f 3)| |$(f 3)|_| "
_2=" ____$(f 5)|___ \\ $(f 5)__) | $(f 7)/ __/ $(f 8)|_____| "
_3=" _____$(f 6)|___ / $(f 7) |_ \\ $(f 7) ___) | $(f 9)|____/ "
_4=" _ _ $(f 10) | || | $(f 10) | || |_ $(f 10) |__ _| $(f 7) |_| "
_5=" ____ $(f 9) | ___| $(f 9) |___ \ $(f 9) ___) | $(f 9) |____/ "
_6=" __ $(f 9) / /_ $(f 9)| '_ \ $(f 9)| (_) | $(f 9) \___/ "
_7=" _____ $(f 9) |___ | $(f 9) / / $(f 9) / / $(f 9) /_/ "
_8=" ___ $(f 9) ( _ ) $(f 9) / _ \ $(f 9)| (_) |$(f 9) \___/ "
_9=" ___ $(f 9) / _ \ $(f 9) | (_) |$(f 9) \__, |$(f 7) /_/ "
eval echo -e '"'$(date +"%T" | tr : c | cut -b 1-5 | sed 's/./${_&}\\033[4A/g')'"'
echo -e "\\033[5B"
Try this:
Host#User> date +"%H:%M"
09:47
Host#User>
In bash/ Ubuntu,
If there is a ASCII art file: "ascii-art" in the following
|__ __| ____|/ ____|__ __|
| | | |__ | (___ | |
| | | __| \___ \ | |
| | | |____ ____) | | |
|_| |______|_____/ |_| Client ${CLIENT_ID}
Is there anyway to pass the variable "${CLIENT_ID}" into the ascii-art every time we call it?
The way we call it at the moment:
cat ascii-art
The following ways don't work
1. cat ascii-art | CLIENT_ID="1"
or
Add one more line in the first line of the file "ascii-art"
. command_line_parse.sh -c ${CLIENT_ID}
|__ __| ____|/ ____|__ __|
| | | |__ | (___ | |
| | | __| \___ \ | |
| | | |____ ____) | | |
|_| |______|_____/ |_| Client ${CLIENT_ID}
Then
cat ascii-art | CLIENT_ID="1"
Could any guru enlighten? Thanks.
The envsubst tool is written for exactly this purpose:
CLIENT_ID=foo envsubst ascii-art
This is a preferable tool to sed, which restricts the range of possible values (if you had a / in your id, or even worse a semicolon followed by another sed command, serious bugs could ensue).
See also TemplateFiles on the Wooledge wiki, which includes a native-bash implementation for systems without GNU gettext (which includes envsubst).
The following evaluates the echo command for the contents of the file:
CLIENT_ID=1000 eval "$(cat <<EOC
echo -e "$(<ascii-art)"
EOC
)"
CLIENT_ID=1000 assigns environment variable for the eval command
eval accepts a here document as its single argument
$(<ascii-art), in Bash, does the same as $(cat ascii-art)
EDIT regarding the scary eval
It's true that we should avoid using eval. But we should also understand the
purpose of the command and do use it when appropriate. We should understand
the security risks, and decide whether we should, or we shouldn't use eval
in certain situations.
The Bash Hackers Wiki gives a good description
of eval:
Perhaps the easiest way to think about eval is that it works in the same way
as running bash -c "bash codeā¦" from a script, except in the case of
eval, the given code is executed in the current shell environment rather
than a child process.
So eval just executes the shell code we pass. How often we execute
external commands from Bash scripts? I guess, quite often. And the commands
are just trusted executables which may well be Bash scripts themselves.
Then why should one be scared of evaluating some echo "trusted content"?
It is up to the user(OP) to decide whether it is safe to use eval in certain
situation. However, this answer definitely gives him an option; it is an
alternate solution. So I don't understand the downvote on this answer.
First: look at the programs figlet, toilet or cowasy. These are probably finished implementation of what you want.
If you want to write it yourself:
sed 's/${CLIENT_ID}/42/g' ascii-art
Modified from RotatingPieces' answer above
First modify the "ascii-art" file, and change "${CLIENT_ID}" into "CLIENT_ID_ART"
|__ __| ____|/ ____|__ __|
| | | |__ | (___ | |
| | | __| \___ \ | |
| | | |____ ____) | | |
|_| |______|_____/ |_| Client CLIENT_ID_ART
Now the following approach might not be very elegant, but it works perfectly
CLIENT_ID="1" # The ${CLIENT_ID} will actually be from the command line parser
echo "sed 's/CLIENT_ID_ART/"${CLIENT_ID}"/g' ascii-art > call_art
chmod +x call_art
./call_art &
rm -f call_art
The above will print out the following in the output
|__ __| ____|/ ____|__ __|
| | | |__ | (___ | |
| | | __| \___ \ | |
| | | |____ ____) | | |
|_| |______|_____/ |_| Client 1
I get these errors when trying to use: export PS1='ascii text at bottom'.
bash: command substitution: line 1: syntax error near unexpected token |'
bash: command substitution: line 1:/ ^ \ | |_) |'
bash: command substitution: line 3: syntax error near unexpected token |'
bash: command substitution: line 3: \ /\ / / _____ \ | |\ ---) |'
Could someone explain why this doesn't work?
________________. ___ .______
/ | / \ | _ \
| (-----| |----`/ ^ \ | |_) |
\ \ | | / /_\ \ | /
.------) | | | / _____ \ | |\ \-------.
|_________/ |__| /__/ \__\| _| `.________|
____ __ ____ ___ .______ ________.
\ \ / \ / / / \ | _ \ / |
\ \/ \/ / / ^ \ | |_) || (-----`
\ / / /_\ \ | / \ \
\ /\ / / _____ \ | |\ \---) |
\__/ \__/ /__/ \__\|__| `._______/
PS1 is not just a plain string; in it, certain characters have meaning to them. You can find a surprisingly long document telling you more about bash prompts than you ever wanted to know here; it's a bit dated, but most of it should still hold. The particular problem you run into is that backslashes and backticks need to be escaped -- backslashes because they're used to escape things, and backticks because they're used for command substitutions -- and newlines are best replaced with the \n control sequence to avoid mishaps with lines that end in \. Ultimately, you want the effect of writing
export PS1=' ________________. ___ .______ \n / | / \\ | _ \\\n | (-----| |----\`/ ^ \\ | |_) |\n \\ \\ | | / /_\\ \\ | /\n.------) | | | / _____ \\ | |\\ \\-------.\n|_________/ |__| /__/ \\__\\| _| \`.________|\n____ __ ____ ___ .______ ________.\n\\ \\ / \\ / / / \\ | _ \\ / |\n \\ \\/ \\/ / / ^ \\ | |_) || (-----\`\n \\ / / /_\\ \\ | / \\ \\\n \\ /\\ / / _____ \\ | |\\ \\---) |\n \\__/ \\__/ /__/ \\__\\|__| \`._______/'
...which is somewhat unwieldy. A way to do this on the fly so that it is easier on the eyes is
PS1=' ________________. ___ .______
/ | / \ | _ \
| (-----| |----`/ ^ \ | |_) |
\ \ | | / /_\ \ | /
.------) | | | / _____ \ | |\ \-------.
|_________/ |__| /__/ \__\| _| `.________|
____ __ ____ ___ .______ ________.
\ \ / \ / / / \ | _ \ / |
\ \/ \/ / / ^ \ | |_) || (-----`
\ / / /_\ \ | / \ \
\ /\ / / _____ \ | |\ \---) |
\__/ \__/ /__/ \__\|__| `._______/'
PS1="${PS1//\\/\\\\}"
PS1="${PS1//\`/\\\`}"
PS1="${PS1//
/\\n}"
export PS1 # <-- this isn't really necessary, by the way. PS1 is not
# usually used by processes the shell spawns.
Here ${variable//pattern/replacement} is a bash-specific parameter expansion that expands to the value of $variable with all occurrences of pattern replaced with replacement. That is to say:
PS1="${PS1//\\/\\\\}" # replaces \ with \\
PS1="${PS1//\`/\\\`}" # replaces ` with \`
PS1="${PS1// # replaces newlines with \n
/\\n}"