Cat redirection auto kill? - linux

I'm trying to do the following :
cat > somefile "some text" <ctrl+d>; clear; some other program
but without having to press
<"ctrl + d">
so that line will create the file and then run some other program. I tried echo "some text" > somefile; but there are too many special chars for that. Anyone know a way around this

I think what you may be looking for is something along these lines:
pax> cat >tempfile ; tput clear ; someprog
Enter your data here for tempfile
<ctrl-d>
**screen clears and someprog runs**
The end-file CTRL-D isn't part of the command you enter, it's part of the input stream for the cat command.
If you don't want to use the input stream, you're either going to have to work out the echo variant (learn to embrace the wonderful world of shell escapes - you can get around most of them by just using single quotes instead of double ones), or simply create your input file in advance and use something like:
cp sourcefile tempfile ; tput clear ; someprog

If you wish to write some text in somefile in multiple lines or with special characters, you should try this. EOF is treated as a special string here that will terminate cat automatically when found but it could be anything else.
cat > somefile << EOF
some text
EOF
some other program

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

how to insert ctrl+d into my linux script?

I want to make the following commands:
cat > template.txt
[enter in the terminal]
text
[Ctrl+d in the terminal]
in a script.
Is there a way to tell the script to do enter\Ctrl d?
Is there a way to create a file and write to it in script?
I didn't find anything that worked for me.
Thanks.
A Here Document is kind of like a script version of what you're talking about, I think, although it is not entirely clear to me from your description.
#!/bin/bash
cat > template.txt <<- EOF
Here
is some
text.
EOF
Ctrl-D itself is the EOF character, ASCII 4.
When you want an interactieve user enter lines and add them to your file until the user enters an ^D you can use the next script:
echo "Please give input"
while read -r line; do
echo "Enter next line or ^D"
echo "${line}" >> template.txt
done
echo "After loop"
You do not have to check for ^D, that will be recognized by read without doing something extra.So you do not need to use CTRL-V CTRL-D in vi.
No, there isn't. How should the script know when your user is finished entering text?

Reading from STDIN, performing commands, then Outputting to STDOUT in Bash

I need to:
Accept STDIN in my script from a pipe
save it to a temp file so that I don't modify the original source
perform operations on the temp file to generate some output
output to STDOUT
Here is my script:
#!/bin/bash
temp=$(cat)
sed 's/the/THE/g' <temp
echo "$temp"
Right now, I am just trying to get it to be able to replace all occurences of "the" with "THE".
Here is the sample text:
the quick brown fox jumped over the lazy
brown dog the quick
brown fox jumped
over
Here is my command line:
cat test.txt | ./hwscript >hwscriptout
"test.txt" contains the sample text, "hwscript" is the script, "hwscriptout" is the output
However, when I look at the output file, nothing has changed (all of occurences of "the" remain uncapitalized). When I do the sed command on the command line instead of the script, it works though. I also tried to use $(sed) instead of sed but when I did that, the command returned an error:
"./hwscript: line 5: s/the/THE/g: no such file or directory"
I have tried to search for a solution but could not find one.
Help is appreciated, thank you.
save it to a temp file so that I don't modify the original source
Anything received via stdin is just a stream of data, disconnected from wherever it originated from: whatever you do with that stream has no effect whatsoever on its origin.
Thus, there is no need to involve a temporary file - simply modify stdin input as needed.
#!/bin/bash
sed 's/the/THE/g' # without a filename operand or pipe input, this will read from stdin
# Without an output redirection, the output will go to stdout.
As you can tell, in this simple case you may as well use the sed command directly, without creating a script.
Use this:
temp=$(sed 's/the/THE/' <<<"$temp")
or
temp=$(printf "%s" "$temp" | sed 's/the/THE/')
You were telling sed to process a file named temp, not the contents of the variable $temp. You also weren't saving the result anywhere, so echo "$temp" simply prints the old value
Here is a way to do it as you described it
#!/bin/sh
# Read the input and append to tmp file
while read LINE; do
echo ${LINE} >> yourtmpfile
done
# Edit the file in place
sed -i '' 's/the/THE/g' yourtmpfile
#Output the result
cat yourtmpfile
rm yourtmpfile
And here is a simpler way without a tmp file
#!/bin/sh
# Read the input and output the line after sed
while read LINE; do
echo ${LINE} | sed 's/the/THE/g'
done

Looping through lines in a file in bash, without using stdin

I am foxed by the following situation.
I have a file list.txt that I want to run through line by line, in a loop, in bash. A typical line in list.txt has spaces in. The problem is that the loop contains a "read" command. I want to write this loop in bash rather than something like perl. I can't do it :-(
Here's how I would usually write a loop to read from a file line by line:
while read p; do
echo $p
echo "Hit enter for the next one."
read x
done < list.txt
This doesn't work though, because of course "read x" will be reading from list.txt rather than the keyboard.
And this doesn't work either:
for i in `cat list.txt`; do
echo $i
echo "Hit enter for the next one."
read x
done
because the lines in list.txt have spaces in.
I have two proposed solutions, both of which stink:
1) I could edit list.txt, and globally replace all spaces with "THERE_SHOULD_BE_A_SPACE_HERE" . I could then use something like sed, within my loop, to replace THERE_SHOULD_BE_A_SPACE_HERE with a space and I'd be all set. I don't like this for the stupid reason that it will fail if any of the lines in list.txt contain the phrase THERE_SHOULD_BE_A_SPACE_HERE (so malicious users can mess me up).
2) I could use the while loop with stdin and then in each loop I could actually launch e.g. a new terminal, which would be unaffected by the goings-on involving stdin in the original shell. I tried this and I did get it to work, but it was ugly: I want to wrap all this up in a shell script and I don't want that shell script to be randomly opening new windows. What would be nice, and what might somehow be the answer to this question, would be if I could figure out how to somehow invoke a new shell in the command and feed commands to it without feeding stdin to it, but I can't get it to work. For example this doesn't work and I don't really know why:
while read p; do
bash -c "echo $p; echo ""Press enter for the next one.""; read x;";
done < list.txt
This attempt seems to fail because "read x", despite being in a different shell somehow, is still seemingly reading from list.txt. But I feel like I might be close with this one -- who knows.
Help!
You must open as a different file descriptor
while read p <&3; do
echo "$p"
echo 'Hit enter for the next one'
read x
done 3< list.txt
Update: Just ignore the lengthy discussion in the comments below. It has nothing to do with the question or this answer.
I would probably count lines in a file and iterate each of those using eg. sed. It is also possible to read infinitely from stdin by changing while condition to: while true; and exit reading with ctrl+c.
line=0 lines=$(sed -n '$=' in.file)
while [ $line -lt $lines ]
do
let line++
sed -n "${line}p" in.file
echo "Hit enter for the next ${line} of ${lines}."
read -s x
done
AWK is also great tool for this. Simple way to iterate through input would be like:
awk '{ print $0; printf "%s", "Hit enter for the next"; getline < "-" }' file
As an alternative, you can read from stderr, which by default is connected to the tty as well. The following then also includes a test for that assumption:
(
tty -s <& 2|| exit 1
while read -r line; do
echo "$line"
echo 'Hit enter'
read x <& 2
done < file
)

Dont want to press Ctrl +D to end a file. Any alternative

I want a linux cmd to write the value of a variable into a file. Heres what i have,
x=$(cat /home/kate/Documents/Desktop/New-ACE-Deploy/deploy/ace/deploysetup/ConfFiles/online_ace_stable-m4.5.conf)
echo $x
cd /etc/apache2/sites-enabled
cat > online_ace_stable-m4.5.conf
echo "$x" >> "/etc/apache2/sites-enabled/online_ace_stable-m4.5.conf"
But i have to press Ctrl +D to end. I dont want to do it. Any alternatives.
Remove the cat > online_ace_stable-m4.5.conf line and you should be fine with regards to pressing Ctrl+D. If the file may exist before you run the script, you want to additionally replace >> (appending) on the last line with > (overwriting).
If you really need to explicitly make sure the file exists and is empty, use echo -n > online_ace_stable-m4.5.conf.
Your cat command on the 4th line is incorrect. It is missing a file parameter. Without this parameter is copies stdin to stdout. This goes on until stdin is closed, hence you need to use CTRL-D
In order to fix your problem, change the line it to:
cat online_ace_stable-m4.5.conf
(Note the > is gone)
If you want to create an empty (new) file, use touch instead of cat:
touch online_ace_stable-m4.5.conf
or directly echo to the file:
echo "$x" > "/etc/apache2/sites-enabled/online_ace_stable-m4.5.conf"
as it it not require to first create it and make sure that old contents are not kept. (Note the single > instead of the double >>)

Resources