Я нашел решение, с помощью cut
и a while
- цикл
#!/bin/bash
RUNDIR=$1
n=2
TMPDIR=
while [ $(echo $RUNDIR | cut -d '/' -f$(printf $n)) ]; do
TMPDIR=$TMPDIR'/'$(echo $RUNDIR | cut -d '/' -f$(printf $n))
if [ -a $TMPDIR ]; then
echo $TMPDIR' exists'
else
echo $TMPDIR' does not exist; creating directory...'
mkdir $TMPDIR
fi
n=$(printf $(($n + 1)))
done
Существует ли более компактный способ сделать это?
Raw read
не будет блокироваться, если труба не пуста - он вернет столько байт, сколько доступно в трубе, даже если вы запросите больше.
Вы можете воспользоваться этим и запускать hexdump -C
при каждом успешном возврате от read
.
#define _BSD_SOURCE
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#define N (8*512) //pipe size on my system as shown in `ulimit -a`
static char buf[N];
int main(){
ssize_t nread;
FILE* p;
for(;;){
do { nread = read(0, buf, N); }while (nread < 0 && errno == EINTR);
if(nread == 0) return 0; //EOF
if(nread < 0) goto error;
p = popen("hexdump -C", "w"); if(!p) goto error;
if(fwrite(buf, sizeof(char), nread, p) != nread) goto error;
pclose(p);
}
return 0;
error:
perror(""); return 1;
}
Вы можете сохранить это, например, как shovel.c
, а затем make shovel
(или gcc shovel.c -o shovel
) и использовать его в своей трубе.
Или, если вас это не интересует, вот ruby сниппет, который должен делать то же самое:
tail -f file |
ruby -e 'PSIZE=8*512;
while(bytes = STDIN.readpartial(PSIZE));
IO.popen("hexdump -C","w") {|p| p.syswrite(bytes) }
end '
Если вы хотите получить что-то дешевое, что просто печатает шестнадцатеричные данные в том виде, в каком они появляются вы можете использовать этот perl скрипт:
perl -e '$| = 1; $i = 1;
while(1){
sysread(STDIN,$ch,1) or exit;
printf "%02x%s",ord($ch),$i++%16==0?"\n":" ";
}'
А если вы действительно хотите прочитать до блока и запустить hexdump:
perl -e '$| = 1; $i = 1; $rin = ""; vec($rin, fileno(STDIN), 1) = 1;
open(F,"|hexdump -C") or die;
while(1){
$nfound = select($rout=$rin, undef, undef, 0);
if($nfound==1){
sysread(STDIN,$data,999) or exit;
syswrite(F,$data) or die;
}else{
close(F);
open(F,"|hexdump -C") or die;
select($rout=$rin, undef, undef, undef);
}
}'