Best way to create table-like CLI display in Bash?
Clash Royale CLAN TAG#URR8PPP
up vote
0
down vote
favorite
I'm working on a Bash script for massive USB flash memory testing (using f3
under the hood). I need to display a table-like interface with multiple columns and cells.
Currently I'm using printf
with and it looks like this:
I have a separate function running for each drive that write out text to a log file. These log files are parsed to display the information to the user.
As you can see some rows have offsets that shouldn't be there but I can't get rid of them It doesn't seem to be caused by long strings being printed. I don't know what's this.
Another problems I have is the refresh time and the need to manually clear and redraw the whole screen at times, due to ocasional stderr messages appearing there from grep
or cat
when some files don't read properly.
I'm currently doing a partial rewrite of this script and I what I could od better in regard to printing out the data on the screen. I thought about looking into ncurses
but that seems like a bit too complicated thing and would probably make things way to complex for me to maintain.
I wonder if there is a way for me to dump the echo
or print
commands to a text file and then execute that all at once to basically have a text "backbuffer" so my refresh can be more consistent and faster?
I would also want to be able to listen for user's keystrokes and react to that in the background but that's not a priority.
Maybe there's a better way to do this kind of thing in Bash, that I don't know of?
bash command-line printf text-user-interface
add a comment |Â
up vote
0
down vote
favorite
I'm working on a Bash script for massive USB flash memory testing (using f3
under the hood). I need to display a table-like interface with multiple columns and cells.
Currently I'm using printf
with and it looks like this:
I have a separate function running for each drive that write out text to a log file. These log files are parsed to display the information to the user.
As you can see some rows have offsets that shouldn't be there but I can't get rid of them It doesn't seem to be caused by long strings being printed. I don't know what's this.
Another problems I have is the refresh time and the need to manually clear and redraw the whole screen at times, due to ocasional stderr messages appearing there from grep
or cat
when some files don't read properly.
I'm currently doing a partial rewrite of this script and I what I could od better in regard to printing out the data on the screen. I thought about looking into ncurses
but that seems like a bit too complicated thing and would probably make things way to complex for me to maintain.
I wonder if there is a way for me to dump the echo
or print
commands to a text file and then execute that all at once to basically have a text "backbuffer" so my refresh can be more consistent and faster?
I would also want to be able to listen for user's keystrokes and react to that in the background but that's not a priority.
Maybe there's a better way to do this kind of thing in Bash, that I don't know of?
bash command-line printf text-user-interface
1
Have you tried ncurses?
â Narà «nasK
Nov 29 '17 at 12:06
I haven't tried it, but I wondered if maybe there's a simpler way that wouldn't require me to learn it.
â unfa
Nov 29 '17 at 12:21
Possibly there are some TABs or other characters that have a display width other than 1, or multi-byte characters in your data. See also Why is printf "shrinking" umlaut?
â Stéphane Chazelas
Nov 29 '17 at 14:08
add a comment |Â
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I'm working on a Bash script for massive USB flash memory testing (using f3
under the hood). I need to display a table-like interface with multiple columns and cells.
Currently I'm using printf
with and it looks like this:
I have a separate function running for each drive that write out text to a log file. These log files are parsed to display the information to the user.
As you can see some rows have offsets that shouldn't be there but I can't get rid of them It doesn't seem to be caused by long strings being printed. I don't know what's this.
Another problems I have is the refresh time and the need to manually clear and redraw the whole screen at times, due to ocasional stderr messages appearing there from grep
or cat
when some files don't read properly.
I'm currently doing a partial rewrite of this script and I what I could od better in regard to printing out the data on the screen. I thought about looking into ncurses
but that seems like a bit too complicated thing and would probably make things way to complex for me to maintain.
I wonder if there is a way for me to dump the echo
or print
commands to a text file and then execute that all at once to basically have a text "backbuffer" so my refresh can be more consistent and faster?
I would also want to be able to listen for user's keystrokes and react to that in the background but that's not a priority.
Maybe there's a better way to do this kind of thing in Bash, that I don't know of?
bash command-line printf text-user-interface
I'm working on a Bash script for massive USB flash memory testing (using f3
under the hood). I need to display a table-like interface with multiple columns and cells.
Currently I'm using printf
with and it looks like this:
I have a separate function running for each drive that write out text to a log file. These log files are parsed to display the information to the user.
As you can see some rows have offsets that shouldn't be there but I can't get rid of them It doesn't seem to be caused by long strings being printed. I don't know what's this.
Another problems I have is the refresh time and the need to manually clear and redraw the whole screen at times, due to ocasional stderr messages appearing there from grep
or cat
when some files don't read properly.
I'm currently doing a partial rewrite of this script and I what I could od better in regard to printing out the data on the screen. I thought about looking into ncurses
but that seems like a bit too complicated thing and would probably make things way to complex for me to maintain.
I wonder if there is a way for me to dump the echo
or print
commands to a text file and then execute that all at once to basically have a text "backbuffer" so my refresh can be more consistent and faster?
I would also want to be able to listen for user's keystrokes and react to that in the background but that's not a priority.
Maybe there's a better way to do this kind of thing in Bash, that I don't know of?
bash command-line printf text-user-interface
asked Nov 29 '17 at 11:43
unfa
516212
516212
1
Have you tried ncurses?
â Narà «nasK
Nov 29 '17 at 12:06
I haven't tried it, but I wondered if maybe there's a simpler way that wouldn't require me to learn it.
â unfa
Nov 29 '17 at 12:21
Possibly there are some TABs or other characters that have a display width other than 1, or multi-byte characters in your data. See also Why is printf "shrinking" umlaut?
â Stéphane Chazelas
Nov 29 '17 at 14:08
add a comment |Â
1
Have you tried ncurses?
â Narà «nasK
Nov 29 '17 at 12:06
I haven't tried it, but I wondered if maybe there's a simpler way that wouldn't require me to learn it.
â unfa
Nov 29 '17 at 12:21
Possibly there are some TABs or other characters that have a display width other than 1, or multi-byte characters in your data. See also Why is printf "shrinking" umlaut?
â Stéphane Chazelas
Nov 29 '17 at 14:08
1
1
Have you tried ncurses?
â Narà «nasK
Nov 29 '17 at 12:06
Have you tried ncurses?
â Narà «nasK
Nov 29 '17 at 12:06
I haven't tried it, but I wondered if maybe there's a simpler way that wouldn't require me to learn it.
â unfa
Nov 29 '17 at 12:21
I haven't tried it, but I wondered if maybe there's a simpler way that wouldn't require me to learn it.
â unfa
Nov 29 '17 at 12:21
Possibly there are some TABs or other characters that have a display width other than 1, or multi-byte characters in your data. See also Why is printf "shrinking" umlaut?
â Stéphane Chazelas
Nov 29 '17 at 14:08
Possibly there are some TABs or other characters that have a display width other than 1, or multi-byte characters in your data. See also Why is printf "shrinking" umlaut?
â Stéphane Chazelas
Nov 29 '17 at 14:08
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
0
down vote
You could use tput
to move the cursor around, for example tput cup 0 0; echo test
will put write "test" to the top left of the screen.
Alternatively, if you wanted to use a buffered approach, you could dump lines to a file, clear the screen and cat the file:
# In program setup
TEMPFILE=$(mktemp) # Create temporary file
trap "rm -f $TEMPFILE" EXIT # Remove temporary on exit
# Main lopp
while true
do
echo "TEST" >$TEMPFILE # Clear file and set first line with >
date >>$TEMPFILE # Append lines to file with >>
clear # Clear the screen
cat $TEMPFILE # Dump the file
sleep 1 # Just for testing to avoid high CPU
done
Comment out the trap
line if you want to leave the temporary file behind for debugging.
add a comment |Â
up vote
0
down vote
I think you have nearly achieved what you set out to do, albeit with a few minor bugs and possibly some performance problems. Personally, I would first try to solve the bugs, then try to understand where the performance could be improved. However regarding your refresh rate, even programs like top or watch usually run with a refresh every 2 or 1 seconds and this is usually sufficient. You don't say, what rate you are trying to achieve.
There is a similar Stackexchange question, which has two answers/suggestions,
- Use the program
dialog
which is something else to learn. - Shows the creation of bash functions, to clear, reset, write text at a position on the screen, which is a similar set of functions that you would probably use in
ncurses
, but has the advantage of using echo (a bash built in function) so it doesn't bear the overhead of running/usr/bin/printf
to format the output.
Taking your problems in turn.
errors being printed from background commands.
Redirect, stderr either to/dev/null
if you just want to discard it or to a file for later processing.Columns bug, show your code, input data nd required output, then we can make suggestions. This bug might be an affect of bug #1, so solve #1 first then address this if it still exists.
Performance, (edit your question) and add your code so that we can see what you are doing and make suggestions.
The other way is to use a different script interpreter, there are so many which to choose depends on which ones you are familiar with. (awk, python, perl, other shells, ...). However if you were not going to use ncurses, the principle would be similar to the bash
function definitions shown in the 2nd answer above.
1
I would tend to agree that this is a bug issue. My biggest concern is that OP has ".... a separate function for each ....". I hope OP means ".... an instance of the same function for each......". Assuming the latter then the usb() function just needs to standardise what is written to the log file (fixed width/delimited etc) and most of the issues should be sorted. Personally I would also write the usb states to a 'model' and then draw the screen with a 'view' a la MVC. Easy maintenance.
â bu5hman
Nov 29 '17 at 14:29
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
You could use tput
to move the cursor around, for example tput cup 0 0; echo test
will put write "test" to the top left of the screen.
Alternatively, if you wanted to use a buffered approach, you could dump lines to a file, clear the screen and cat the file:
# In program setup
TEMPFILE=$(mktemp) # Create temporary file
trap "rm -f $TEMPFILE" EXIT # Remove temporary on exit
# Main lopp
while true
do
echo "TEST" >$TEMPFILE # Clear file and set first line with >
date >>$TEMPFILE # Append lines to file with >>
clear # Clear the screen
cat $TEMPFILE # Dump the file
sleep 1 # Just for testing to avoid high CPU
done
Comment out the trap
line if you want to leave the temporary file behind for debugging.
add a comment |Â
up vote
0
down vote
You could use tput
to move the cursor around, for example tput cup 0 0; echo test
will put write "test" to the top left of the screen.
Alternatively, if you wanted to use a buffered approach, you could dump lines to a file, clear the screen and cat the file:
# In program setup
TEMPFILE=$(mktemp) # Create temporary file
trap "rm -f $TEMPFILE" EXIT # Remove temporary on exit
# Main lopp
while true
do
echo "TEST" >$TEMPFILE # Clear file and set first line with >
date >>$TEMPFILE # Append lines to file with >>
clear # Clear the screen
cat $TEMPFILE # Dump the file
sleep 1 # Just for testing to avoid high CPU
done
Comment out the trap
line if you want to leave the temporary file behind for debugging.
add a comment |Â
up vote
0
down vote
up vote
0
down vote
You could use tput
to move the cursor around, for example tput cup 0 0; echo test
will put write "test" to the top left of the screen.
Alternatively, if you wanted to use a buffered approach, you could dump lines to a file, clear the screen and cat the file:
# In program setup
TEMPFILE=$(mktemp) # Create temporary file
trap "rm -f $TEMPFILE" EXIT # Remove temporary on exit
# Main lopp
while true
do
echo "TEST" >$TEMPFILE # Clear file and set first line with >
date >>$TEMPFILE # Append lines to file with >>
clear # Clear the screen
cat $TEMPFILE # Dump the file
sleep 1 # Just for testing to avoid high CPU
done
Comment out the trap
line if you want to leave the temporary file behind for debugging.
You could use tput
to move the cursor around, for example tput cup 0 0; echo test
will put write "test" to the top left of the screen.
Alternatively, if you wanted to use a buffered approach, you could dump lines to a file, clear the screen and cat the file:
# In program setup
TEMPFILE=$(mktemp) # Create temporary file
trap "rm -f $TEMPFILE" EXIT # Remove temporary on exit
# Main lopp
while true
do
echo "TEST" >$TEMPFILE # Clear file and set first line with >
date >>$TEMPFILE # Append lines to file with >>
clear # Clear the screen
cat $TEMPFILE # Dump the file
sleep 1 # Just for testing to avoid high CPU
done
Comment out the trap
line if you want to leave the temporary file behind for debugging.
answered Nov 29 '17 at 13:43
Silas Parker
1714
1714
add a comment |Â
add a comment |Â
up vote
0
down vote
I think you have nearly achieved what you set out to do, albeit with a few minor bugs and possibly some performance problems. Personally, I would first try to solve the bugs, then try to understand where the performance could be improved. However regarding your refresh rate, even programs like top or watch usually run with a refresh every 2 or 1 seconds and this is usually sufficient. You don't say, what rate you are trying to achieve.
There is a similar Stackexchange question, which has two answers/suggestions,
- Use the program
dialog
which is something else to learn. - Shows the creation of bash functions, to clear, reset, write text at a position on the screen, which is a similar set of functions that you would probably use in
ncurses
, but has the advantage of using echo (a bash built in function) so it doesn't bear the overhead of running/usr/bin/printf
to format the output.
Taking your problems in turn.
errors being printed from background commands.
Redirect, stderr either to/dev/null
if you just want to discard it or to a file for later processing.Columns bug, show your code, input data nd required output, then we can make suggestions. This bug might be an affect of bug #1, so solve #1 first then address this if it still exists.
Performance, (edit your question) and add your code so that we can see what you are doing and make suggestions.
The other way is to use a different script interpreter, there are so many which to choose depends on which ones you are familiar with. (awk, python, perl, other shells, ...). However if you were not going to use ncurses, the principle would be similar to the bash
function definitions shown in the 2nd answer above.
1
I would tend to agree that this is a bug issue. My biggest concern is that OP has ".... a separate function for each ....". I hope OP means ".... an instance of the same function for each......". Assuming the latter then the usb() function just needs to standardise what is written to the log file (fixed width/delimited etc) and most of the issues should be sorted. Personally I would also write the usb states to a 'model' and then draw the screen with a 'view' a la MVC. Easy maintenance.
â bu5hman
Nov 29 '17 at 14:29
add a comment |Â
up vote
0
down vote
I think you have nearly achieved what you set out to do, albeit with a few minor bugs and possibly some performance problems. Personally, I would first try to solve the bugs, then try to understand where the performance could be improved. However regarding your refresh rate, even programs like top or watch usually run with a refresh every 2 or 1 seconds and this is usually sufficient. You don't say, what rate you are trying to achieve.
There is a similar Stackexchange question, which has two answers/suggestions,
- Use the program
dialog
which is something else to learn. - Shows the creation of bash functions, to clear, reset, write text at a position on the screen, which is a similar set of functions that you would probably use in
ncurses
, but has the advantage of using echo (a bash built in function) so it doesn't bear the overhead of running/usr/bin/printf
to format the output.
Taking your problems in turn.
errors being printed from background commands.
Redirect, stderr either to/dev/null
if you just want to discard it or to a file for later processing.Columns bug, show your code, input data nd required output, then we can make suggestions. This bug might be an affect of bug #1, so solve #1 first then address this if it still exists.
Performance, (edit your question) and add your code so that we can see what you are doing and make suggestions.
The other way is to use a different script interpreter, there are so many which to choose depends on which ones you are familiar with. (awk, python, perl, other shells, ...). However if you were not going to use ncurses, the principle would be similar to the bash
function definitions shown in the 2nd answer above.
1
I would tend to agree that this is a bug issue. My biggest concern is that OP has ".... a separate function for each ....". I hope OP means ".... an instance of the same function for each......". Assuming the latter then the usb() function just needs to standardise what is written to the log file (fixed width/delimited etc) and most of the issues should be sorted. Personally I would also write the usb states to a 'model' and then draw the screen with a 'view' a la MVC. Easy maintenance.
â bu5hman
Nov 29 '17 at 14:29
add a comment |Â
up vote
0
down vote
up vote
0
down vote
I think you have nearly achieved what you set out to do, albeit with a few minor bugs and possibly some performance problems. Personally, I would first try to solve the bugs, then try to understand where the performance could be improved. However regarding your refresh rate, even programs like top or watch usually run with a refresh every 2 or 1 seconds and this is usually sufficient. You don't say, what rate you are trying to achieve.
There is a similar Stackexchange question, which has two answers/suggestions,
- Use the program
dialog
which is something else to learn. - Shows the creation of bash functions, to clear, reset, write text at a position on the screen, which is a similar set of functions that you would probably use in
ncurses
, but has the advantage of using echo (a bash built in function) so it doesn't bear the overhead of running/usr/bin/printf
to format the output.
Taking your problems in turn.
errors being printed from background commands.
Redirect, stderr either to/dev/null
if you just want to discard it or to a file for later processing.Columns bug, show your code, input data nd required output, then we can make suggestions. This bug might be an affect of bug #1, so solve #1 first then address this if it still exists.
Performance, (edit your question) and add your code so that we can see what you are doing and make suggestions.
The other way is to use a different script interpreter, there are so many which to choose depends on which ones you are familiar with. (awk, python, perl, other shells, ...). However if you were not going to use ncurses, the principle would be similar to the bash
function definitions shown in the 2nd answer above.
I think you have nearly achieved what you set out to do, albeit with a few minor bugs and possibly some performance problems. Personally, I would first try to solve the bugs, then try to understand where the performance could be improved. However regarding your refresh rate, even programs like top or watch usually run with a refresh every 2 or 1 seconds and this is usually sufficient. You don't say, what rate you are trying to achieve.
There is a similar Stackexchange question, which has two answers/suggestions,
- Use the program
dialog
which is something else to learn. - Shows the creation of bash functions, to clear, reset, write text at a position on the screen, which is a similar set of functions that you would probably use in
ncurses
, but has the advantage of using echo (a bash built in function) so it doesn't bear the overhead of running/usr/bin/printf
to format the output.
Taking your problems in turn.
errors being printed from background commands.
Redirect, stderr either to/dev/null
if you just want to discard it or to a file for later processing.Columns bug, show your code, input data nd required output, then we can make suggestions. This bug might be an affect of bug #1, so solve #1 first then address this if it still exists.
Performance, (edit your question) and add your code so that we can see what you are doing and make suggestions.
The other way is to use a different script interpreter, there are so many which to choose depends on which ones you are familiar with. (awk, python, perl, other shells, ...). However if you were not going to use ncurses, the principle would be similar to the bash
function definitions shown in the 2nd answer above.
answered Nov 29 '17 at 13:50
X Tian
7,31111836
7,31111836
1
I would tend to agree that this is a bug issue. My biggest concern is that OP has ".... a separate function for each ....". I hope OP means ".... an instance of the same function for each......". Assuming the latter then the usb() function just needs to standardise what is written to the log file (fixed width/delimited etc) and most of the issues should be sorted. Personally I would also write the usb states to a 'model' and then draw the screen with a 'view' a la MVC. Easy maintenance.
â bu5hman
Nov 29 '17 at 14:29
add a comment |Â
1
I would tend to agree that this is a bug issue. My biggest concern is that OP has ".... a separate function for each ....". I hope OP means ".... an instance of the same function for each......". Assuming the latter then the usb() function just needs to standardise what is written to the log file (fixed width/delimited etc) and most of the issues should be sorted. Personally I would also write the usb states to a 'model' and then draw the screen with a 'view' a la MVC. Easy maintenance.
â bu5hman
Nov 29 '17 at 14:29
1
1
I would tend to agree that this is a bug issue. My biggest concern is that OP has ".... a separate function for each ....". I hope OP means ".... an instance of the same function for each......". Assuming the latter then the usb() function just needs to standardise what is written to the log file (fixed width/delimited etc) and most of the issues should be sorted. Personally I would also write the usb states to a 'model' and then draw the screen with a 'view' a la MVC. Easy maintenance.
â bu5hman
Nov 29 '17 at 14:29
I would tend to agree that this is a bug issue. My biggest concern is that OP has ".... a separate function for each ....". I hope OP means ".... an instance of the same function for each......". Assuming the latter then the usb() function just needs to standardise what is written to the log file (fixed width/delimited etc) and most of the issues should be sorted. Personally I would also write the usb states to a 'model' and then draw the screen with a 'view' a la MVC. Easy maintenance.
â bu5hman
Nov 29 '17 at 14:29
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f407721%2fbest-way-to-create-table-like-cli-display-in-bash%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
1
Have you tried ncurses?
â Narà «nasK
Nov 29 '17 at 12:06
I haven't tried it, but I wondered if maybe there's a simpler way that wouldn't require me to learn it.
â unfa
Nov 29 '17 at 12:21
Possibly there are some TABs or other characters that have a display width other than 1, or multi-byte characters in your data. See also Why is printf "shrinking" umlaut?
â Stéphane Chazelas
Nov 29 '17 at 14:08