D7VK byl vydán ve verzi 1.2. Jedná se o fork DXVK implementující překlad volání Direct3D 5, 6 a 7 na Vulkan. DXVK zvládá Direct3D 8, 9, 10 a 11.
Byla vydána verze 12.0.0 knihovny libvirt (Wikipedie) zastřešující různé virtualizační technologie a vytvářející jednotné rozhraní pro správu virtuálních strojů. Současně byl ve verzi 12.0.0 vydán související modul pro Python libvirt-python. Přehled novinek v poznámkách k vydání.
CreepyLink.com je nový zkracovač URL adres, 'díky kterému budou vaše odkazy vypadat tak podezřele, jak je to jen možné'. Například odkaz na abclinuxu.cz tento zkracovač převádí do podoby 'https://netflix.web-safe.link/logger_8oIlgs_free_money.php'. Dle prohlášení autora je CreepyLink alternativou ke zkracovači ShadyURL (repozitář na githubu), který dnes již bohužel není v provozu.
Na blogu Raspberry Pi byla představena rozšiřující deska Raspberry Pi AI HAT+ 2 s akcelerátorem Hailo-10 a 8 GB RAM. Na rozdíl od předchozí Raspberry Pi AI HAT+ podporuje generativní AI. Cena desky je 130 dolarů.
Wikipedie slaví 25. výročí svého založení. Vznikla 15. ledna 2001 jako doplňkový projekt k dnes již neexistující encyklopedii Nupedia. Doména wikipedia.org byla zaregistrována 12. ledna 2001. Zítra proběhne v Praze Večer svobodné kultury, který pořádá spolek Wikimedia ČR.
Po více než dvou letech od vydání předchozí verze 2.12 byla vydána nová stabilní verze 2.14 systémového zavaděče GNU GRUB (GRand Unified Bootloader, Wikipedie). Přehled novinek v souboru NEWS a v aktualizované dokumentaci.
Google Chrome 144 byl prohlášen za stabilní. Nejnovější stabilní verze 144.0.7559.59 přináší řadu novinek z hlediska uživatelů i vývojářů. Podrobný přehled v poznámkách k vydání. Opraveno bylo 10 bezpečnostních chyb. Vylepšeny byly také nástroje pro vývojáře (YouTube).
Microsoft zveřejnil zdrojový kód XAML Studia a uvolnil ho pod MIT licencí. XAML Studio je nástroj ze světa Windows, určený pro tvorbu uživatelského rozhraní aplikací pomocí XAML (Extensible Application Markup Language). Stalo se tak zhruba po osmi letech od prvního prohlášení Microsoftu, že se tento kód chystá zveřejnit.
TimeCapsule, 'časová kapsle', je jazykový model trénovaný výhradně na datech z určitých míst a časových období, aby se tak napodobila autentická slovní zásoba, způsob vyjadřování a názory dané doby. Na Hugging face jsou k dispozici modely natrénované na historických textech dostupných v oblasti Londýna mezi lety 1800 až 1875.
Radicle byl vydán ve verzi 1.6.0 s kódovým jménem Amaryllis. Jedná se o distribuovanou alternativu k softwarům pro spolupráci jako např. GitLab.
Jak zařídit, aby příkaz cp ukazoval "progress bar" (ukazatel postupu) podobně jako wget? Stačí trocha poměrně nechutného čarování s strace a skript je na světě.
Tiskni
Sdílej:
Ale jako hack je to opravdu luxusní (jen kdyby strace nebylo tak zatraceně pomalé
).
/*
* cwp.c: catenate with progress
*
* Copyright (c) 2001 Chris Lightfoot. All rights reserved.
*
*/
static char rcsid[] = "$Id: cwp.c,v 1.2 2001/01/19 00:26:17 chris Exp $";
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/time.h>
#define BLOCKSIZE 65536
#define TIMESTEP 10. /* number of seconds over which rate will be calculated */
int columns = 80; /* width of screen */
/* timeoffset:
* Returns the number of seconds since some time.
*/
float timeoffset(const time_t t0) {
struct timeval tv;
gettimeofday(&tv, NULL);
tv.tv_sec -= t0;
return (float)tv.tv_sec + 1e-6 * (float)tv.tv_usec;
}
/* size:
* Return a string describing the size of something.
*/
char *strsize(const int width, const int len) {
static char str[64];
if (len > 10000000)
sprintf(str, "% *.1f Mb", width - 3, (float)len / 1048576.);
else if (len > 10000)
sprintf(str, "% *.1f Kb", width - 3, (float)len / 1024.);
else
sprintf(str, "% *d b", width - 2, len);
return str;
}
/* file_copy_progress:
* Copy data from a file to some file descriptor, with a progress indicator
* which indicates what fraction of the file has been copied.
*/
void file_copy_progress(char *f, int o, size_t size) {
int i;
ssize_t j, total = 0;
char *buf;
time_t tst;
float t0 = 0., t1, t2;
ssize_t n0, n1, n2;
i = open(f, O_RDONLY);
if (i == -1) {
perror(f);
return;
}
buf = (char*)malloc(BLOCKSIZE);
tst = time(NULL);
t0 = timeoffset(tst);
n0 = 0;
while ((j = read(i, buf, BLOCKSIZE))) {
ssize_t k;
float rate;
if (j == -1 && errno != EINTR) {
fprintf(stderr, "\n");
perror(f);
close(i);
free(buf);
return;
}
for (k = 0; k < j; ) {
ssize_t l;
l = write(o, buf + k, j - k);
if (l == -1 && errno != EINTR) {
fprintf(stderr, "\n");
perror(f);
close(i);
free(buf);
return;
}
k += l;
total += l;
}
t1 = timeoffset(tst);
if ((t1 - t0) > TIMESTEP / 2.) {
t2 = timeoffset(tst);
n2 = total;
}
if ((t1 - t0) > TIMESTEP) {
t0 = t2;
n0 = n2;
}
/* Print a progress indicator. */
fprintf(stderr, "%.*s: written %s/",
columns - 55,
f, strsize(9, total));
fprintf(stderr, "%s % 5.1f%% ",
strsize(9, size),
100. * ((float)total/(float)size));
rate = ((float)(total - n0) / (t1 - t0));
if (rate < 0.) rate = 0.;
if (rate > 1e7)
fprintf(stderr, "% 5.1f Mb/s", rate / 1048576.0);
else if (rate > 1e4)
fprintf(stderr, "% 5.1f Kb/s", rate / 1024.0);
else
fprintf(stderr, "% 5.1f b/s", rate);
fprintf(stderr, " \r");
}
free(buf);
}
/* pipe_copy_progress:
* Copy data from a nonseekable thing to a file descriptor, with a progress
* indicator which indicates how many bytes have been copied.
*/
void pipe_copy_progress(char *f, int i, int o) {
ssize_t j, total = 0;
char *buf;
time_t tst;
float t0 = 0., t1, t2;
ssize_t n0, n1, n2;
buf = (char*)malloc(BLOCKSIZE);
tst = time(NULL);
t0 = timeoffset(tst);
n0 = 0;
while ((j = read(i, buf, BLOCKSIZE))) {
ssize_t k;
float rate;
if (j == -1 && errno != EINTR) {
fprintf(stderr, "\n");
perror(f);
close(i);
free(buf);
return;
}
for (k = 0; k < j; ) {
ssize_t l;
l = write(o, buf + k, j - k);
if (l == -1 && errno != EINTR) {
fprintf(stderr, "\n");
perror(f);
close(i);
free(buf);
return;
}
k += l;
total += l;
}
t1 = timeoffset(tst);
if ((t1 - t0) > TIMESTEP / 2.) {
t2 = timeoffset(tst);
n2 = total;
}
if ((t1 - t0) > TIMESTEP) {
t0 = t2;
n0 = n2;
}
/* Print a progress indicator. */
fprintf(stderr, "%.*s: written %s ",
columns - 20,
f, strsize(9, total));
rate = ((float)(total - n0) / (t1 - t0));
if (rate < 0.) rate = 0.;
if (rate > 1e7)
fprintf(stderr, "% 5.1f Mb/s", rate / 1048576.0);
else if (rate > 1e4)
fprintf(stderr, "% 5.1f Kb/s", rate / 1024.0);
else
fprintf(stderr, "% 5.1f b/s", rate);
fprintf(stderr, " \r");
}
free(buf);
}
int main(int argc, char **argv) {
char *s = getenv("COLUMNS");
int i;
if (s && (i = atoi(s)) && i > 0) columns = i;
signal(SIGPIPE, SIG_IGN); /* We would rather get an EPIPE return. */
/* FIXME should we reopen stderr as /dev/tty if !isatty(2)? */
/* Copy stdin to stdout. */
if (argc == 1)
pipe_copy_progress("standard input", 0, 1);
else if (argc == 2 &&
(!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h"))) {
fprintf(stderr,
"cwp: catenate with progress\n"
"%s\n"
"\n"
" cwp file ...\n"
" catenate the given files on standard output, giving a\n"
" progress indication for each file on standard error\n"
"\n"
" cwp\n"
" copy standard input to standard output, giving a\n"
" progress indication on standard error\n"
"\n"
"Copyright (c) 2001 Chris Lightfoot <chris@ex-parrot.com>. Redistribute freely.\n",
rcsid);
} else {
char **a;
for (a = argv + 1; *a; ++a) {
struct stat st;
stat(*a, &st);
if (S_ISREG(st.st_mode)) {
file_copy_progress(*a, 1, st.st_size);
fprintf(stderr, "\n");
} else {
int fd;
fd = open(*a, O_RDONLY);
if (fd == -1) perror(*a);
else pipe_copy_progress(*a, fd, 1);
}
}
}
}