Tmux doesn't show line breaks when calling `shell` to display output from Bash command - linux

Given the following text file "HelloWorld.txt"
Hello World
~~~line break~~~
This is a text file
In .tmux.conf, I config the following setup:
bind F1 shell "cat HelloWorld.txt"
When I use this shortcut, Tmux prints the following:
Hello World
This is a text file
That line break just disappears mysteriously.
How can I preserve line breaks?

I couldn't find a bug report but this seems to be how tmux' run-shell command behaves. The workaround I found is to pipe the output via sed to replace each blank line with a space.
Your example would then become like this:
bind F1 run-shell "cat HelloWorld.txt | sed 's/^$/ /'"

Related

VI read line not giving desired output

I have a file called test, I open it using vi as such:
vi test
Now I want to insert a line through a shell command, for simplicity I use a printf:
:r! printf %s hello
However the line that is entered is
tests
i.e. the name of the file with a s appended.
If I enter the same command in terminal directly, it works fine.
What I want to do is ultimately be able to encode a string in base64 and enter it on the same line as where my cursor is in vi, so that I won't have to copy the string in a separate terminal, encode it, and copy it back into vi. How can I do this? What am I doing wrong?
The first stage of processing a command line in vim is expanding it. % is expanded to the name of the current file — test in your case. %s is expanded to tests.
To avoid expanding protect the special character with a backslash:
:r! printf \%s hello

How to write a string in a file using vim editor from command line

I want to create a new file using vi editor from command line and add a string to it multiple times say 100. Using vi -S command.script file.txt is supposed to do the trick where a new file file.txt will be created and the commands given in command.script file can write to this file. My command.script contains
:%100a hello world
:wq
But its's not working, what I am doing wrong?
If you interactively execute :%100a hello world in a Vim session, you'll get E488: Trailing characters. Looking up :help :a:
:{range}a[ppend][!] Insert several lines of text below the specified
line. If the {range} is missing, the text will be
inserted after the current line. [...]
These two commands will keep on asking for lines, until you type a line
containing only a ".".
tells you that the text has to be put in following lines (and concluded by a line with only a . character).
Or did you mean to use the normal mode a command? (That one takes a [count] to multiply; your %100 range is wrong, too!)
You can also use the low-level function append(), repeating the string with repeat().
summary
$append
hello world
[...]
hello world
.
execute "$normal! 100ahello world\<CR>"
" Easier with o instead of a:
$normal! 100ohello world
call append('$', repeat(['hello world'], 100))
non-Vim alternatives
But honestly, if that is your real use case (and not just a simplified toy example), you don't need Vim at all for this. Here's one example for the Bash shell:
$ for i in $(seq 100); do echo "hello world" >> file.txt; done

Random text in linux terminal

Sup guys. How I can make terminal to show the text that I want ? And how to edit the text that is already displayed
For example terminal is showing now:
user#host: sudo writetext
bash: writetext: command not found
How to edit this text to be displayed like this
user#host: sudo writetext 5
writelext line 1 executed
writelext line 2 executed
writelext line 3 executed
writelext line 4 executed
writelext line 5 executed
I don't need the program to work, i just need to know how to display random text in terminal
You can add an alias to the bashrc
vim ~/.bashrc
Go to the end of the file
add line: alias writeText='echo "write text executed"'
Then reload the bashrc with: source ~/.bashrc
After this you should be able to call the alias by typing in writeText
Here you can also add a more advanced echo function.
If you want to pass parameters you have to write a separate function as described here:
Passing argument to alias in bash
Write a shell script and add echo commands inside to display whatever u want to display
There are many ways to print text to stdout, you should read some man pages:
man echo
man print
man printf
more powerful tools:
sed, awk ...
Examples:
seq
kent$ seq -f "whatever %g" 5
whatever 1
whatever 2
whatever 3
whatever 4
whatever 5
awk
kent$ awk -v v=5 'BEGIN{for(i=1;i<=v;i++)print "whatever "i}'
whatever 1
whatever 2
whatever 3
whatever 4
whatever 5
If you're trying "make the terminal display text that I will type."
You could try read, assign a variable to the read and then echo it
read text
echo "${text}"

Shell Script Edit Files Line

I am not that good on linux shell script and I need little help.
I want to edit a file via script (finding the line and edit).
The Original line is:
# JVM_OPTS="$JVM_OPTS -Djava.rmi.server.hostname=< hostname >"
I want to uncomment and replaye hostname with 127.0.0.1
JVM_OPTS="$JVM_OPTS -Djava.rmi.server.hostname=127.0.0.1"
You can refer to the set command, change the filename with the name you are working at,
sed -i 's## JVM_OPTS="$JVM_OPTS -Djava.rmi.server.hostname=< hostname >"#JVM_OPTS="$JVM_OPTS -Djava.rmi.server.hostname=127.0.0.1"#' filename
Fine answers, but they don't do anything by way of TEACHING the gentleman how and why it works.
If you were using the mundane text editor, ed, you would use three commands after invoking the command "ed filename":
s/^# //
s/< hostname>/127.0.0.1/
w
So, you can use a pipe to submit those commands directly to ed, specifying "-" as its first argument so that it doesn't bother you by reporting character counts upon reading in and writing out the file:
( echo 's/^# //'; echo 's//127.0.0.1/'; echo w ) | ed - filename
You don't need to echo 'q' also because ed will automatically quit when it runs out of input or encounters "end of file" (you can simulate this on the keyboard by just hitting the CTRL-D key rather than actually typing q ).
Here's one way to do it:
sed -i -e 's/# \(JVM_OPTS=.*=\).*/\1127.0.0.1"/' path/to/file
That is, replace the line with the text captured within the group \(JVM_OPTS=.*=\), so everything from JVM_OPTS= until another = sign, and append 127.0.0.1" to the end.
If there might be other lines in the file starting with # JVM_OPTS=,
then you could make the pattern matching more strict, for example:
sed -i -e 's/# \(JVM_OPTS="$JVM_OPTS -Djava.rmi.server.hostname=\).*/\1127.0.0.1"/' path/to/file

How to show line number when executing bash script

I have a test script which has a lot of commands and will generate lots of output, I use set -x or set -v and set -e, so the script would stop when error occurs. However, it's still rather difficult for me to locate which line did the execution stop in order to locate the problem.
Is there a method which can output the line number of the script before each line is executed?
Or output the line number before the command exhibition generated by set -x?
Or any method which can deal with my script line location problem would be a great help.
Thanks.
You mention that you're already using -x. The variable PS4 denotes the value is the prompt printed before the command line is echoed when the -x option is set and defaults to : followed by space.
You can change PS4 to emit the LINENO (The line number in the script or shell function currently executing).
For example, if your script reads:
$ cat script
foo=10
echo ${foo}
echo $((2 + 2))
Executing it thus would print line numbers:
$ PS4='Line ${LINENO}: ' bash -x script
Line 1: foo=10
Line 2: echo 10
10
Line 3: echo 4
4
http://wiki.bash-hackers.org/scripting/debuggingtips gives the ultimate PS4 that would output everything you will possibly need for tracing:
export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
In Bash, $LINENO contains the line number where the script currently executing.
If you need to know the line number where the function was called, try $BASH_LINENO. Note that this variable is an array.
For example:
#!/bin/bash
function log() {
echo "LINENO: ${LINENO}"
echo "BASH_LINENO: ${BASH_LINENO[*]}"
}
function foo() {
log "$#"
}
foo "$#"
See here for details of Bash variables.
PS4 with value $LINENO is what you need,
E.g. Following script (myScript.sh):
#!/bin/bash -xv
PS4='${LINENO}: '
echo "Hello"
echo "World"
Output would be:
./myScript.sh
+echo Hello
3 : Hello
+echo World
4 : World
Workaround for shells without LINENO
In a fairly sophisticated script I wouldn't like to see all line numbers; rather I would like to be in control of the output.
Define a function
echo_line_no () {
grep -n "$1" $0 | sed "s/echo_line_no//"
# grep the line(s) containing input $1 with line numbers
# replace the function name with nothing
} # echo_line_no
Use it with quotes like
echo_line_no "this is a simple comment with a line number"
Output is
16 "this is a simple comment with a line number"
if the number of this line in the source file is 16.
This basically answers the question How to show line number when executing bash script for users of ash or other shells without LINENO.
Anything more to add?
Sure. Why do you need this? How do you work with this? What can you do with this? Is this simple approach really sufficient or useful? Why do you want to tinker with this at all?
Want to know more? Read reflections on debugging
Simple (but powerful) solution: Place echo around the code you think that causes the problem and move the echo line by line until the messages does not appear anymore on screen - because the script has stop because of an error before.
Even more powerful solution: Install bashdb the bash debugger and debug the script line by line
If you're using $LINENO within a function, it will cache the first occurrence. Instead use ${BASH_LINENO[0]}

Resources