3

I have a Python script, EulerianCycle.py, and an input file, euleriancycle.txt.

I am able to get the correct results by doing py EulerianCycle euleriancycle.txt > cat euleriancycleout.txt into the current folder (py is an alias for python3).

However, I have another folder in this current one called outputs, to which I want all my output files be directed.

I've tried py EulerianCycle.py euleriancycle.txt | cd outputs/ | cat > euleriancycleout.txt

And py EulerianCycle.py euleriancycle.txt | cat >cd outputs/euleriancycleout.txt

which gives me the broken pipe error.

7

If py EulerianCycle.py euleriancycle.txt writes to the standard output stream (which I assume it does, since otherwise you wouldn't be able to pipe it to cat) then cat is entirely superfluous here - you can redirect standard output directly, specifying either absolute or relative path to your output file:

py EulerianCycle.py euleriancycle.txt > outputs/euleriancycleout.txt

(note: the directory outputs/ must already exist).


Neither of your other commands works the way you might imagine.

  • in py EulerianCycle euleriancycle.txt > cat euleriancycleout.txt, the shell creates a file named cat in the current directory, and redirects the output of py EulerianCycle to it, passing both euleriancycle.txt and euleriancycleout.txt to it as input arguments.

  • in py EulerianCycle.py euleriancycle.txt | cat >cd outputs/euleriancycleout.txt, the shell creates a file named cd in the current directory, cat reads outputs/euleriancycleout.txt and writes it to file cd, ignoring standard input from the pipe (cat only reads standard input when it is given no input files, or an explicit -).

Perhaps what you were aiming for here was to pipe the output to a subshell like:

py EulerianCycle.py euleriancycle.txt | (cd outputs; cat > euleriancycleout.txt)

or

py EulerianCycle.py euleriancycle.txt | (cd outputs && cat > euleriancycleout.txt)

Here, cat reads the subshell's standard input - which is provided by the pipe - after changing to the target directory. The second version only creates euleriancycleout.txt if the cd command succeeds; the first creates it in the current directory if the cd fails.

6
  • It would be great if you could add something about the initial broken pipe error which I think occurs due to the cd-shell-builtin which doesnt accept std-in.
    – mook765
    Jul 4 at 14:58
  • okay yes this makes sense. Your code works as intended. I also did see a random file named "cd" in the cwd. Thanks for explaining the unintentional actions of the commands I tried as well. for @mook765, the broken pipe error is as follows: py EulerianCycle.py euleriancycle.txt | cat >cd outputs/euleriancycleout.txt Traceback (most recent call last): File "/home/user/.../EulerianCycle.py", line 39, in <module> print('->'.join(eulerian_cycle(graph))) BrokenPipeError: [Errno 32] Broken pipe
    – trinity
    Jul 4 at 15:36
  • @Rukhan so presumably that's because cat is reading (instead of writing to) the intended output file, so there's noting actually reading what your python program is sending down the pipe Jul 4 at 15:40
  • @steeldriver Understood! Did not realize that cat's use is for stdin explicitly like cat EulerianCycle.py, where I was trying to make it read stdout and send it down a pipe
    – trinity
    Jul 4 at 15:47
  • @Trinity cat will do that - if you either give it no input files, or give it - as a pseudo input file. But it is not needed here. Jul 4 at 15:57
1

Additionally, you can use:

EulerianCycle.py | tee euleriancycleout.txt

to send the content to the text file and to stdout concurrently in 2 seperate streams. In other words the content will end up both in the text file and printed in the terminal.

I always do it this way as it shows me what wrote, and saves me having to open up vim to check my work.

2
  • Note: This is meant only to provide additional context, in support of the answer above.
    – Nate T
    Jul 6 at 11:38
  • Thanks for the info, really useful!
    – trinity
    Jul 7 at 17:05
-1

Figured out I can use py EulerianCycle.py euleriancycle.txt | cat > euleriancycleout.txt | mv -t outputs/ euleriancycleout.txt

OR

py EulerianCycle.py euleriancycle.txt | cat > euleriancycleout.txt & mv -t outputs/ euleriancycleout.txt

Still open to a possible command that will do this more concisely. :)

edit: code presented is not efficient, see green check marked answer

1
  • You can separate commands on the same line by ";". There isn't any need to use pipes and 'cat' - just redirect: py EulerianCycle.py euleriancycle.txt > euleriancycleout.txt Jul 5 at 4:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.