Sarò onesto, non avevo in mente il suo viso, o meglio l'ho sempre associato a questa figura :) :
Grazie per UNIX, il linguaggio C, il libro "The C Programming Language" (detto K&R).


[...]mmh niente da fare. Iniziano i primi FORTI dubbi. Al che per togliersene un bel po'
%x Time of last access
%X Time of last access as seconds since Epoch
%y Time of last modification
%Y Time of last modification as seconds since Epoch
%z Time of last change
%Z Time of last change as seconds since Epoch
[..]
ma...ma...NON C'È!
[..]
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* inode number */
mode_t st_mode; /* protection */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device ID (if special file) */
off_t st_size; /* total size, in bytes */
blksize_t st_blksize; /* blocksize for file system I/O */
blkcnt_t st_blocks; /* number of 512B blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last status change */
};
[..]
Inode: 524360 Type: regular Mode: 0644 Flags: 0x80000
Generation: 1374299388 Version: 0x00000000:00000001
User: 0 Group: 0 Size: 515
File ACL: 0 Directory ACL: 0
Links: 1 Blockcount: 8
Fragment: Address: 0 Number: 0 Size: 0
ctime: 0x4d62a41b:29f0e708 -- Mon Feb 21 18:42:51 2011
atime: 0x4e44d538:d129cbbc -- Fri Aug 12 09:24:40 2011
mtime: 0x4d62a41b:1d8b1d3c -- Mon Feb 21 18:42:51 2011
crtime: 0x4d62a41b:1d8b1d3c -- Mon Feb 21 18:42:51 2011
Size of extra inode fields: 28
EXTENTS:
(0):2167296

#!/bin/sh
exec > prova.log 2 > &1
echo "queste due linee stampate"
echo "andranno in prova.log"
{math equation="x - 1985" x=$smarty.now|date_format:"%Y"}
{$smarty.get.item}
{$smarty.post.item}
{$smarty.cookies.item}
|
{if $item eq ''} default item value {else} {$item} {/if} |
| {$item|default:'default item value'} |
{foreach from=$projects name=workslist item=project}
{if $smarty.foreach.workslist.iteration is not odd}
{else}
{/if}
{/foreach}
Ancora più elegante potrebbe essere una soluzione con la funzione cycle.
5. Lista separata da un carattere
Ad esempio, se vogliamo stampare una lista di nomi separati da una virgola ma (ovviamente) evitare la virgola finale:
{section name=sectionname loop=$names}
{$names[sectionname]}{if $smarty.section.sectionname.last == false}, {/if}
{/section}
L'output sarebbe qualcosa come:
Warty, Feisty, Karmic, Breezy, Lucid
# Copyright (C) 2010 Lorenzo Sfarra (lorenzosfarra@ubuntu.com)
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
from django.conf.urls.defaults import *
from django.conf import settings
MEDIA_ROOT = settings.MEDIA_ROOT
urlpatterns = patterns('',
(r'^cmd/(?P.*)$', 'terminaljs.terminal.views.cmd'),
(r'^media/(?P.*)$', 'django.views.static.serve',
{'document_root': MEDIA_ROOT}),
(r'^$', 'terminaljs.terminal.views.index'),
)
# Copyright (C) 2010 Lorenzo Sfarra (lorenzosfarra@ubuntu.com)
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
from django.shortcuts import render_to_response
from django.http import HttpResponse
from commands import getoutput
import os.path
# global variable
CWD = "/home/lorenzo"
def index(request):
return render_to_response("index.html")
def is_trusted_command(command):
#TODO: check if it's a trusted command
return True
def cmd(request, command):
global CWD
if command.startswith("cd "):
new_path = command.split(" ")[1]
if not new_path.startswith("/"):
# relative path
new_path = os.path.join(CWD, new_path)
if os.path.isdir(new_path):
CWD = new_path
output = ""
else:
output = "cd: " + new_path + ": No such file or directory"
elif is_trusted_command(command):
output = getoutput("cd %s; %s" %(CWD,command))
else:
output = "Untrusted command."
return HttpResponse(output)
Il lato server è stato realizzato con il web framework Python Django, il lato client sfrutta la libreria JS JQuery anche per le chiamate AJAX.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
<head>
<title>Lorenzo Sfarra :: DJSterminal</title>
<link rel="stylesheet" href="/media/css/terminal.css"/>
<script type="text/javascript"
src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
// You may specify partial version numbers, such as "1" or "1.3",
// with the same result. Doing so will automatically load the
// latest version matching that partial revision pattern
// (e.g. 1.3 would load 1.3.2 today and 1 would load 1.4.2).
google.load("jquery", "1.4.2");
</script>
<script src="/media/js/terminal.js" type="text/javascript">/* Terminal */</script>
<script type="text/javascript">
google.setOnLoadCallback(function() {
/* Handle the enter keycode */
$("#commandline").keypress(function(event) {
if (event.keyCode == '13') {
event.preventDefault();
onEnterKey();
}
});
});
</script>
</head>
<body>
<div id="terminal">
<div id="terminaltop"><img src="/media/css/imgs/buttons.png" alt="buttons" align="left"/> <br/>Javascript Terminal</div>
<!-- Command line -->
<textarea id="commandline" cols="80" rows="15">lorenzo@josie:~$ </textarea>
<!-- End command line -->
</div>
</body>
</html>
/* Copyright (C) 2010 Lorenzo Sfarra (lorenzosfarra@ubuntu.com)
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA.
*/
// The command line prompt
var cliPrompt = "lorenzo@josie:~$ ";
// the server address where the real console exists
var cliHost = "http://localhost:8000/";
function isTrustedCommand(command) {
/**
* Function to check that the given command is trusted.
* @param command the command to check
* @return boolean
*/
// TODO: check that this is a trusted command!
return true;
}
function executeCommand(text, cliPrompt, command) {
/**
* Function to execute the given command through an AJAX call
* and retrieve the result to update the textarea value.
* @param text the current textarea value
* @param cliPrompt the prompt
* @param command the command to execute
*/
// build the URL for the command
remoteCommand = cliHost + "cmd/" + command;
output = "";
// Perform the AJAX call
$.ajax({
url: remoteCommand,
type: 'GET',
dataType: 'text',
error: function(data, textStatus, errorThrown) {
// readyState == 4? Error.
if (data.readyState == 4) {
output = "Connection error.\n"
}
},
success: function(data) {
output = data + "\n";
$("#commandline").val([text, output, cliPrompt].join("\n"));
// Textarea with focus at bottom
$("#commandline").animate({ scrollTop: 99999}, 10);
}
});
}
function onEnterKey() {
/* Function called when a user press the Enter key on its keyboard. */
text = $("#commandline").val();
// Get the command
promptIndex = text.lastIndexOf(cliPrompt);
// build the command
command = text.substring(promptIndex + cliPrompt.length);
if (command == "clear") {
// simply clear the textarea value
$("#commandline").val(cliPrompt);
} else if (isTrustedCommand(command)) {
executeCommand(text, cliPrompt, command);
} else {
output = "Invalid command.";
$("#commandline").val([text,output,cliPrompt].join("\n"));
}
}
L'applicazione è scritta in python ed è già pronto un .deb, oltre ai sorgenti, sulla pagina del progetto.
google blogger post --tags "GoogleCL, terminale, linea di comando, Linux, Google" --title "GoogleCL: Google Command Line Tool" post.html








