Launch nano editor passing piped command - linux

this is a curiosity.
Can i start nano editor from bash, passing a piped command?
this is my situation:
I've a log file with dates formatted in tai64. For print my file i launch:
$> cat /var/log/qmail/current | tai64nlocal
that print what i want.
but i want to view this in nano or another editor in one command. for example:
$> cat /var/log/qmail/current | tai64nlocal > nano
but this doesn't work.
Any suggestion?
Thanks in advance

if you want to nano to open stdin use dash-notation (-):
echo "foo" | nano -
in your case this would translate to
cat /var/log/qmail/current | tai64nlocal | nano -

Use process substitution:
nano <(cat /var/log/qmail/current | tai64nlocal)
Also, you don't need to use cat
nano <(tai64nlocal < /var/log/qmail/current)

It didn't work because you are not using pipes. You are using a redirect which works slightly different.
| vs >
By doing
cat /var/log/qmail/current | tai64nlocal > nano
You are piping cat's stdout to tai64nlocal stdin. Then you redirect it's stdout to a filestream, in this case a file named nano in your pwd.
Based on what you wanted, it partially works because the tai command does both printing and echoing to stdout.
Older versions of nano do not support being piped to though. This was introduced in nano 2.2.
You would do
Command | nano -
The single dash tells nano to open stdin as a pager, like more or less would.

davymartu's command "nano < ( cat /var/log/maillog | tai64nlocal )" generates a syntax error because of the space between "<" and "(". If the space is removed, as it is in konsolebox's examples, the command will execute.

Related

Linux save string to file without ECHO command

I want to save a command to a file (for example I want to save the string "cat /etc/passwd" to a file) but I can't use the echo command.
How can I create and save string to a file directly without using echo command?
You can redirect cat to a file, type the text, and press Control-D when you're done, like this:
cat > file.txt
some text
some more text
^D
By ^D I mean to press Control-D at the end. The line must be empty.
It will not be part of the file, it is just to terminate the input.
Are you avoiding ECHO for security purposes (e.g. you're using a shared terminal and you don't want to leave trace in the shell history of what you've written inside your files) or you're just curious for an alternative method?
Simple alternative to echo:
As someone said, redirecting cat is probably the simpler way to go.
I'd suggest you to manually type your end-of-file, like this:
cat <<EOF > outputfile
> type here
> your
> text
> and finish it with
> EOF
Here's the string you're asking for, as an example:
cat <<EOF > myscript.sh
cat /etc/passwd
EOF
You probably don't want everyone to know you've peeked into that file, but if that's your purpose please notice that wrapping it inside an executable file won't make it more private, as that lines will be logged anyway...
Security - Avoiding history logs etc..
In modern shell, just try adding a space at the beginning of every command and use freely whatever you want.
BTW, my best hint is to avoid using that terminal at all, if you can. If you got two shells (another machine or even just another secure user in the same machine), I'd recommend you using netcat. See here: http://www.thegeekstuff.com/2012/04/nc-command-examples/?utm_source=feedburner
{ { command ls $(dirname $(which cat)) |
grep ^ca't$'; ls /etc/passwd; } |
tr \\n ' '; printf '\n'; } > output-file
But it's probably a lot simpler to just do : printf 'cat /etc/passwd\n'
To be clear, this is a tongue-in-cheek solution. The initial command is an extraordinarily convoluted way to get what you want, and this is intended to be a humorous answer. Perhaps instructive to understand.
I am not sure I understood you correctly but
cat /etc/passwd > target.file
use the > operator to write it to file without echoing
If you need to use it, inside a program :
cat <<EOF >file.txt
some text
some more text
EOF
I would imagine that you are probably trying to print the content of a string to a file, hence you mentioned echo.
You are avoiding this:
echo "cat /etc/passwd" > target.file
You can use a here string combined with cat.
cat > target.file <<< "cat /etc/passwd"
Now the file target.file will contain a string cat /etc/passwd.
$ cat target.file
cat /etc/passwd
$
To create string:
var1=your command
to save a file or variable in a file without echo use:
cat $FILE/VAR1 > /new/file/path

Linux cat command output with new lines to be read using vim

I am trying to open all the files listed in file a.lst:
symptom1.log
symptom2.log
symptom3.log
symptom4.log
But trying the following command:
cat a.lst | tr "\n" " " | vim -
opens only the stdin output
symptom1.log symptom2.log symptom3.log symptom4.log
It doesn't open symptom1.log, symptom2.log, symptom3.log & symptom4.log in vim.
How to open all the files listed in a.lst using vim?
You could use xargs to line upp the arguments to vi:
vim $(cat 1.t | xargs)
or
cat a.lst | xargs vim
If you want them open in split view, use -o (horizontal) or -O (vertical):
cat a.lst | xargs vim -o
cat a.lst | xargs vim -O
while read f ; do cat $f ; done < a.lst | vim -
I like a variation on Qiau's xargs option:
xargs vim < a.lst
This works because the input redirection is applied to the xargs command rather than vim.
If your shell is bash, another option is this:
vim $(<a.lst)
This works because within the $(...), input redirection without a command simply prints the results of the input, hence expanding the file into a list of files for vim to open.
UPDATE:
You mentioned in comments that you are using csh as your shell. So another option for you might be:
vim `cat a.lst`
This should work in POSIX shells as well, but I should point out that backquotes are deprecated in some other shells (notably bash) in favour of the $(...) alternative.
Note that redirection can happen in multiple places on your command line. This should also work in both csh and bash:
< a.lst xargs vim
vim may complain that its input is not coming from a terminal, but it appears to work for me anyway.

How to write stdout to file with colors?

A lot of times (not always) the stdout is displayed in colors. Normally I keep every output log in a different file too. Naturally in the file, the colors are not displayed anymore.
I'd like to know if there's a way (in Linux) to write the output to a file with colors. I'm trying to use tee to write the output of vagrant to a file, this way I can still see the output (when it applies). I want to use it specifically for vagrant (it may change in the future, of course...)
Since many programs will only output color sequences if their stdout is a terminal, a general solution to this problem requires tricking them into believing that the pipe they write to is a terminal. This is possible with the script command from bsdutils:
script -q -c "vagrant up" filename.txt
This will write the output from vagrant up to filename.txt (and the terminal). If echoing is not desirable,
script -q -c "vagrant up" filename > /dev/null
will write it only to the file.
You can save the ANSI sequences that colourise your output to a file:
echo a | grep --color=always . > colour.txt
cat colour.txt
Some programs, though, tend not to use them if their output doesn't go to the terminal (that's why I had to use --color-always with grep).
In Ubuntu, you can install the package bsdutils to output to a text file with ANSI color codes:
script -q -c "ls --color=always" /tmp/t
Install kbtin to generate a clean HTML file:
ls --color=always | ansi2html > /tmp/t.html
Install aha and wkhtmltopdf to generate a nice PDF:
ls --color=always | aha | wkhtmltopdf - /tmp/t.pdf
Use any of the above with tee to display the output also on the console or to save a copy in another file. Example:
ls --color=always | tee /dev/stderr | aha | wkhtmltopdf - /tmp/test.pdf
You can also color your output with echo with different colours and save the coloured output in file. Example
echo -e '\E[37;44m'"Hello World" > my_file
Also You would have to be acquainted with the terminal colour codes
Using tee
< command line > |tee -a 'my_colour_file'
Open your file in cat
cat 'my_colour_file'
Using a named pipe can also work to redirect all output from the pipe with colors to another file
for example
Create a named pipe
mkfifo pipe.fifo
each command line redirect it to the pipe as follows
<command line> > pipe.fifo
In another terminal redirect all messages from the pipe to your file
cat pipe.fifo > 'my_log_file_with_colours'
open your file with cat and see the expected results.
I found out that using the tool called ansi2html.sh
Is the most simple way to export colorful terminal data to html file,
The commands to use it are:
ls --color=always | ansi2html.sh --palette=solarized > ~/Desktop/ls.html
All is needed is to send the output using a pipe and then output the stdout to simple html file
Solution
$ script -q /dev/null -c "your command" > log.txt
$ cat log.txt
Explanation
According to the man page of script, the --quit option only makes sure to be quiet (do not write start and done messages to standard output). Which means that the start and done messages will always be written to the file.
In order to utilize script and discard the output file at the same file, we can simply specify the null device /dev/null to it! Also, redirect the output to our desired destination and the color content will be written to the destination.
I was trying out some of the solutions listed here, and I also realized you could do it with the echo command and the -e flag.
$ echo -e "\e[1;33m This is yellow text \e[0m" > sample.txt
Next, we can view the contents of our sample.txt file.
$ cat sample.txt
Click link to see the output in yellow
Additionally, we can also use tee and pipe it with our echo command:
echo -e "\e[1;33m This is yellow text \e[0m" | tee -a sample.txt
On macOS, script is from the BSD codebase and you can use it like so:
script -q /dev/null mvn dependency:tree mvn-tree.colours.txt
It will run mvn dependency:tree and store the coloured output into mvn-tree.colours.txt
The tee utility supports colours, so you can pipe it to see the command progress:
script -q /dev/null mvn dependency:tree | tee mvn-tree.colours.txt
To get the script manual you can type man script:
SCRIPT(1) BSD General Commands Manual SCRIPT(1)
NAME
script -- make typescript of terminal session
SYNOPSIS
script [-adkpqr] [-F pipe] [-t time] [file [command ...]]
In the RedHat/Rocky/CentOS family, the ansi2html utility does not seem to be available (except for Fedora 32 and up). An equivalent utility is ansifilter from the EPEL repository. Unfortunately, it seems to have been removed from EPEL 8.
script is preinstalled from the util-linux package.
To set up:
yum install ansifilter -y
To use it:
ls --color=always | ansifilter -H > output.html
To generate a pretty PDF (not tested), have ansifilter generate LaTeX output, and then post-process it:
ls --color=always | ansifilter -L | pdflatex >output.pdf
Obviously, combine this with the script utility, or whatever else may be appropriate in your situation.

Bash standard output display and redirection at the same time

In terminal, sometimes I would like to display the standard output and also save it as a backup. but if I use redirection ( > &> etc), it does not display the output in the terminal anymore.
I think I can do for example ls > localbackup.txt | cat localbackup.txt. But it just doesn't feel right. Is there any shortcut to achieve this?
Thank you!
tee is the command you are looking for:
ls | tee localbackup.txt
In addition to using tee to duplicate the output (and it's worth mentioning that tee is able to append to the file instead of overwriting it, by using tee -a, so that you can run several commands in sequence and retain all of the output), you can also use tail -f to "follow" the output file from a parallel process (e.g. a separate terminal):
command1 >localbackup.txt # create output file
command2 >>localbackup.txt # append to output
and from a separate terminal, at the same time:
tail -f localbackup.txt # this will keep outputting as text is appended to the file

Append text to file from command line without using io redirection

How can we append text in a file via a one-line command without using io redirection?
If you don't mind using sed then,
$ cat test
this is line 1
$ sed -i '$ a\this is line 2 without redirection' test
$ cat test
this is line 1
this is line 2 without redirection
As the documentation may be a bit long to go through, some explanations :
-i means an inplace transformation, so all changes will occur in the file you specify
$ is used to specify the last line
a means append a line after
\ is simply used as a delimiter
If you just want to tack something on by hand, then the sed answer will work for you. If instead the text is in file(s) (say file1.txt and file2.txt):
Using Perl:
perl -e 'open(OUT, ">>", "outfile.txt"); print OUT while (<>);' file*.txt
N.B. while the >> may look like an indication of redirection, it is just the file open mode, in this case "append".
You can use the --append feature of tee:
cat file01.txt | tee --append bothFiles.txt
cat file02.txt | tee --append bothFiles.txt
Or shorter,
cat file01.txt file02.txt | tee --append bothFiles.txt
I assume the request for no redirection (>>) comes from the need to use this in xargs or similar. So if that doesn't count, you can mute the output with >/dev/null.
You can use Vim in Ex mode:
ex -sc 'a|BRAVO' -cx file
a append text
x save and close
On Linux/GNU systems, the simplest and cleanest solution is:
dd of=oldfile oflag=append conv=notrunc
Simple and clean, because no quoting or backslashitis is required.
Unfortunately, this also doesn't work on BSD (and so, on Darwin), because their dd has no oflag . Argh! Can anyone suggest how to do it with the BSD dd ?

Resources