Unix pipe into ls
To do that you need xargs
:
which studio | xargs ls -l
From man xargs
:
xargs - build and execute command lines from standard input
To fully understand how pipes work, you can read What is a simple explanation for how pipes work in BASH?:
A Unix pipe connects the STDOUT (standard output) file descriptor of
the first process to the STDIN (standard input) of the second. What
happens then is that when the first process writes to its STDOUT, that
output can be immediately read (from STDIN) by the second process.
Piping the contents of a file to ls
You are looking for the xargs
(transpose arguments) command.
xargs ls < input.txt
You say you want /bin
to be the "input" to ls
, but that's not correct; ls
doesn't do anything with its input. Instead, you want /bin
to be passed as a command-line argument to ls
, as if you had typed ls /bin
.
Input and arguments are completely different things; feeding text to a command as input is not the same as supplying that text as an argument. The difference can be blurred by the fact that many commands, such as cat
, will operate on either their input or their arguments (or both) – but even there, we find an important distinction: what they actually operate on is the content of files whose names are passed as arguments.
The xargs
command was specifically designed to transform between those two things: it interprets its input as a whitespace-separated list of command-line arguments to pass to some other command. That other command is supplied to xargs
as its command-line argument(s), in this case ls
.
Thanks to the input redirection provided by the shell via <
, the arguments xargs
supplies to ls
here come from the input.txt
file.
There are other ways of accomplishing the same thing; for instance, as long as input.txt
does not have so many files in it that they won't fit in a single command line, you can just do this:
ls $(< input.txt)
Both the above command and the xargs
version will treat any spaces in the input.txt
file as separating filenames, so if you have filenames containing space characters, you'll have to do more work to interpret the file properly. Also, note that if any of the filenames contain wildcard/"glob" characters like ?
or *
or [
...]
, the $(<
...)
version will expand them as wildcard patterns, while xargs
will not.
Pipe find command output to ls command
xargs
takes input from stdin and passes it as arguments to some command.
find . -mtime -365 | xargs ls -lth --full-time
# or better with no dirs and handle spaces and quotes in filename
find . -type f -mtime -365 | xargs -d '\n' ls -lth --full-time
# or better - handle newlines in filenames
find . -mtime -365 -print0 | xargs -0 ls -lth --full-time
Pipe printf to ls in Bash?
Many programs don't read from stdin
, not just ls
. It is also possible that a program might not write to stdout
either.
Here is a little experiment that might clarify things. Carry out these steps:
cat > file1
This is file1
^D
The ^D is you pressing <CTRL>+D
, which is the default end-of-file. So, first we are calling the cat
program and redirecting its stdout
to file1
. If you don't supply an input filename then it reads from stdin
, so we type "This is file1".
Now do similar:
cat > file2
This is file2
^D
Now if you:
cat < file1
You get:
This is file1
what if you:
cat file1 | cat file2
or:
cat file2 < file1
Why? Because if you supply an input filename then the cat
program does not read stdin
, just like ls
.
Now, how about:
cat - file1 < file2
By convention the -
means a standard stream, stdin
when reading or stdout
when writing.
Pipelining of cat and ls commands
In the first example you are passing the output of cat file
to the input of ls -l
. Since ls -l
does not take any input, it does not do anything regarding the output of cat file
. However in the second example you are using $(cat file)
which puts the output of cat file
in the place of an argument passed to ls -l
, and this time ls -l
has the text inside file
in the right place for doing something with it. The issue here is noticing the difference between the standard input of a program and the arguments of a program. Standard input is what you have when you call scanf
in C, for example; and the arguments are what you get in the argv
pointer passed as parameter to the main procedure.
Unix - How do you pass / pipe the output of a sed command to a ls command in Unix
Don't parse ls
to get the file size. To get the size of a file on disk, use stat -c '%s' filename
, or to get the size of a stream of characters, use wc -c
.
# size of employee.txt
stat -c '%s' employee.txt
# size without header and footer
sed '1d;$d' employee.txt | wc -c
UNIX Pipe System with Reading and Writing to Execute ls -la Command
Firstly let me tell you what I interpreted from the question:
The child will execute
exec()
and the output ofls -la
should be printed by the parent using pipe.
According to this I fixed your code to give the output of ls -la
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <cstring>
#include <iostream>
char *cmd1[] = { "ls", "-la", NULL };
//for exec each parameter should be a separate string
int main()
{
int fd[2], nbytes;
//char string[] = "ls -la"; //unused variable
char readbuffer[80]; // is a buffer size of 80 enough?
pipe(fd);
pid_t pid = fork();
if(pid == 0) { // child writes to pipe
// open the pipe, call exec here, write output from exec into pipe
dup2(fd[1],1); // stdout goes to fd[1]
close(fd[0]); // read not needed
execvp(cmd1[0],cmd1); //execute command in child
exit(0);
}
else { // parent reads from pipe
// read output from pipe, write to console
close(fd[1]); // write not needed
//read the output of the child to readbuffer using fd[0]
nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
//std::cout << readbuffer << std::endl;
//write also outputs readbuffer
//output readbuffer to STDOUT
write(1, readbuffer, nbytes);
}
exit(0);
}
Can not pipe the output of echo command to ls
When you pipe something into another process, it will be pushed into its STDIN
stream. As ls does not read from stdin, it just ignores that. What you want is that the parameters are passed to the command line of ls
. This can be achieved by using something like this:
my_file="a"
ls -l "$my_file"
Alternatively, you can use xargs which can be used to construct command line parameters from stdin input. In your case, you could use it like
echo "a" | xargs ls -l
It will execute an ls -l [filename]
for each space-separated string of stdin input.
Bash ls and command pipe
You can't pipe stuff into ls
.. You could do something like:
ls -ld $(cut -f 6 -d ':' /etc/passwd | sort -su)
By spawning a new bash to execute the cut | sort
and passing it as a ls
argument
Related Topics
How to Call Accept() for One Socket from Several Threads Simultaneously
How to Confirm Sftp File Delivery
How to Copy an Array in Nasm X86 Assembly for Linux, Porting 16-Bit Dos Code
Linux Kernel Device Driver to Dma from a Device into User-Space Memory
How to Run an X Program from Outside the X Session (E.G. from the Console or Ssh)
What Does the 2> Mean on the Unix Command-Line
How to Build a Docker Image on Windows 10
Memory Access Error Sys_Rt_Sigaction (Signal Handler)
Setting Up a Cronjob on Google Compute Engine
Linux Why Can't I Pipe Find Result to Rm
How to Track Child Process Using Strace
Gcc-Arm-Linux-Gnueabi Command Not Found