Skocz do zawartości

Temat został przeniesiony do archiwum

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

martolo

Zadanie w linuxie

Rekomendowane odpowiedzi

Zadanie polega na wykorzystaniu języka ANSI C do napisania prostego programu powłoki – Microshell. Program ten powinien przyjmować na wejściu polecenia, a następnie wykonywać działania zgodne z ich treścia. Powłoka powinna:

 

punkty opis

1,0 pkt wyświetlać znak zachęty w postaci [{path}] $, gdzie {path} jest scieżką do bieżącego katalogu roboczego

1,0 pkt obsługiwać polecenie cd, działające analogicznie do tego znanego nam z powłoki bash

0,5 pkt. obsługiwać polecenie exit, kończące działanie programu powłoki

0,5 pkt. obsługiwać polecenie help, wyświetlające na ekranie informacje o autorze programu i oferowanych przez niego funkcjonalnościach

2,0 pkt. obsługiwać dwa inne, dowolnie wybrane polecenia powłoki (chodzi tutaj np. o własną, samodzielną, prostą implementację dwóch poleceń)

2,0 pkt. przyjmować polecenia odwołujące się przez nazwę do skryptow i programów znajdujacych się w katalogach opisanych wartoscią zmiennej środowiskowej PATH oraz umożliwiać wywołanie tych skryptów i programów z argumentami

1,0 pkt wypisywać komunikat błędu, gdy niemożliwe jest poprawne zinterpretowanie polecenia

2,0 pkt. posiadać tzw. dodatkowe bajery (w zależności od stopnia skomplikowania problemu), np. wyświetlanie loginu aktualnie zalogowanego użytkownika, obsługę kolorów, obsługę argumentów w cudzysłowach, sensowną obsługę sygnałów (np. Ctrl+Z), obsługę historii poleceń, uzupełnianie składni, itp.

 

Z powodów niezależnych ode mnie opuściłam lwią część zajęć i nie mam pojęcia jak się zabrać za to zadanie. Nie proszę o napisanie za mnie kodu, a o pomoc i naprowadzenie w dobrą stronę. ;)

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
Gość Nareszcie

Zatem naprowadzenie.

Masz do napisania program w C, ktory dzialajac w petli bedzie pobieral polecenie, parsowal je, przesylal do systemu operacyjnego i wyswietlal otrzymany wynik.

Na poczatku zacznij od napisania programu, ktory wykona punkt 4 - obsluga polecenia help. Na oko dziesiec linijek kodu, ktory pozniej musisz skompilowac i uruchomic. Wiesz jak to zrobic?

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Nie wiem czy jest to optymalne, ale działa :P

 

#include <unistd.h>
#include <stdio.h>
#include <stdio.h>
int main()
{
char polecenie[100];
do
{
gets(polecenie);
if(strcmp(polecenie,"help")==0)
{
printf("informacje blablabla iformacje\n");
printf("informacje blablabla iformacje\n");
printf("informacje blablabla iformacje\n");
}
} while(strcmp(polecenie,"koniec"));
return 0;
}

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
Gość Nareszcie

Jak na pierwsza wersje jest dobrze.

To teraz trzy zadania:

1. Przepisz program z uzyciem konstrukcji switch / case;

2. Zapoznaj sie z funkcjami "system", "exec" oraz "execl" i uzyj jednej z nich do wykonania polecenia pierwszego. Czesc z nich moze wymagac zalaczenia bibliotego stdlib.h albo innej;

3. Zastap slowo "koniec" slowemn "exit", by spelnic wymagania punktu trzeciego.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Nie potrafię napisać tego programu z użyciem switch. Przy kompilacji wyskakuje błąd, ponieważ chce wartości jako liczby, a ja podaję mu cale słowa. Szukałam odpowiedzi w internecie i znalazłam tylko użycie tej instrukcji dla pojedynczych znaków a nie całych słów. Aktualnie mój program wyglada tak:

 

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFFER_SIZE 1024

int system(const char *string);
int strcmp(const char *s1, const char *s2);


int main()
{
char polecenie[100];
do
{
printf("{");
system("pwd");
printf("} $");

fgets(polecenie, sizeof(polecenie), stdin);
if(strcmp(polecenie,"help")==0)
{
printf("informacje o autorze\n");
}
} while(strcmp(polecenie,"exit"));
return 0;
}

 

Exit nie zatrzymuje dzialania programu,a help nie wyświetla informacji o autorze. :/

Program wypisuje dobrą ścieżkę, ale nie mogę ująć ścieżki w dwie klamry żeby to było w jednej linii. Jak to naprawić?

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Pokaż jak próbowałeś użyć switcha i jaki konkretnie błąd kompilator wyświetlił.

 

Odnośnie tego wyżej, to na początek sprawdź co fgets wczytuje

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

1) switch działa tylko dla typów całkowitych (char, int, long itp.) a C-string to tablica

2) używaj funkcji

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

1) switch działa tylko dla typów całkowitych (char, int, long itp.) a C-string to tablica

2) używaj funkcji

 

Nie do końca rozumiem jakiej funkcji mam użyć. Skoro switch nie działa dla tablic, to go sobie odpuścić?

Wpisałam fgets, ponieważ samo gets mogło przekroczyć rozmiar bufora, czy coś takiego. :/

Nie wiem co teraz, aktualnie dla linuxa nie działa nic, bo nawet aktualna scieżka nie jest w tych klamrach. Wygląda to tak:

{

SCIEŻKA

} $

 

Chyba nie tak to powinno wyglądać :/

 

EDIT: Dopisałam printf za fgets zeby sprawdzic co wczytuje i jest ok, jako polecenie jest zapamiętywane to co wpiszę.

 

EDIT 2: Udało się naprawić działanie wyswietlania sciezki, help i exit. Kod wyglada teraz tak:

 

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFFER_SIZE 1024

int system(const char *string);
int strcmp(const char *s1, const char *s2);


int main()
{
char polecenie[100];
char cwd[1000];
do
{
getcwd(cwd,sizeof(cwd));
printf("{");
printf("%s",cwd);
printf("} $");

fgets(polecenie, sizeof(polecenie), stdin);
if(strcmp(polecenie,"help"))
{
printf("informacje o autorze\n");
}
} while(strcmp(polecenie,"exit")==0);
return 0;
}

 

EDIT 3: ODWOŁUJE, DZIAŁA TYLKO POKAZYWANIE ŚCIEŻKI

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

fgets wczytuje znak(i) nowej linii, który jest uwzględniany przy porównaniu.

Na chama można w warunkach dodać \n Lepiej jednak będzie się pozbyć tego dodatkowego znaku (lub znaków, kwestia systemu).

Proste ale nie uniwersalne: if(polecenie[strlen(polecenie) - 1] == '\n') polecenie[strlen(polecenie) - 1] = 0;

 

Niepoprawne warunki przy if i while.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Wow, dziękuję bardzo.

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFFER_SIZE 1024

int system(const char *string);
int strcmp(const char *s1, const char *s2);


int main()
{
char polecenie[100];
char cwd[100];
do
{
getcwd(cwd,sizeof(cwd));
printf("{");
printf("%s",cwd);
printf("} $");
fgets(polecenie, sizeof(polecenie), stdin);
if(polecenie[strlen(polecenie) - 1] == '\n') polecenie[strlen(polecenie) - 1] = 0;
if(strcmp(polecenie, "help")==0)
{
printf("informacje o autorze\n");
}
} while(strcmp(polecenie,"exit")!=0);
return 0;
}

 

Teraz polecenia działają, więc 3 z 8 wymagań programu jest spełnionych, szkoda tylko, że to 3 najprostsze polecenia. :(

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Od czegoś trzeba zacząć :)

 

Proponuję uprościć wypisywanie znaku zachęty. Nie ma sensu robić tego na 3 printfach, jak można to ogarnąć jednym.

Działanie polecenia help dobrze jest zamknąć w funkcji.

 

Przerobiłbym pętlę, tak żeby działała w nieskończoność, a interpretacja polecenia była w zestawie/drabince if-ów. Wydaje mi się, że wtedy będzie można łatwiej zaimplementować wypisanie informacji o błędnym poleceniu. W tym celu można zrobić drabinkę if-ów (pseudokod):

if(komenda1) wykionaj1;
else if(komenda2) wykonaj2;
else if(komenda3) wykonaj3;
else nie_znam_polecenia;

Będzie to przynajmniej 0,5 punktu za przedostatnie zadanie. Nie wiem jakie są wymagania prowadzącego, czy wystarczy sama informacja o błędnej składni/nieznanym poleceniu, czy ma być dokładniej sprawdzane np. niepoprawne argumenty do polecenia i wypisanie poprawnej składni.

 

Do przerwania nieskończonej pętli można użyć polecenia break lub po prostu return czy exit. Do doczytania co dokładnie robią.

 

Program dosyć łatwo rozbudować o wypisywanie loginu użytkownika, wystarczy użyć funkcji getlogin_r, podobnie do getcwd.

 

Następnie zająłbym się chyba obsługą polecenia cd, bo to też wstęp do bardziej skomplikowanych.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
Proponuję uprościć wypisywanie znaku zachęty. Nie ma sensu robić tego na 3 printfach, jak można to ogarnąć jednym.

Zrobione :)

Działanie polecenia help dobrze jest zamknąć w funkcji.

Ale nie jest to konieczne? Jadę po najmniejszej linii oporu :cool:

Przerobiłbym pętlę, tak żeby działała w nieskończoność, a interpretacja polecenia była w zestawie/drabince if-ów. Wydaje mi się, że wtedy będzie można łatwiej zaimplementować wypisanie informacji o błędnym poleceniu.

Jest!

Do przerwania nieskończonej pętli można użyć polecenia break lub po prostu return czy exit. Do doczytania co dokładnie robią.

Zrobione!

Program dosyć łatwo rozbudować o wypisywanie loginu użytkownika, wystarczy użyć funkcji getlogin_r, podobnie do getcwd.

To również sie udało!

Następnie zająłbym się chyba obsługą polecenia cd, bo to też wstęp do bardziej skomplikowanych.

I tu się zaczynają prawdziwe schody. Czytałam o tym nieco, zrobiłam nawet swoją wersję, jednak działała w taki sposób, że najpierw wpisywało się "cd" a potem w kolejnej linii do jakiego folderu chce się przenieść. Także zalatuje biedą. ;'(

 

Obecny program:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_SIZE 1024

int system(const char *string);
int strcmp(const char *s1, const char *s2);
int chdir(const char *path);
int getlogin_r(char *buf, size_t bufsize);

int main()
{
printf("\n\n         Witaj w moim programie microshell! Jesli potrzebujesz pomocy-wpisz help\n\n\n");

char polecenie[100];
char cwd[100];
char login[100];

while(1)
   {
   getcwd(cwd,sizeof(cwd));
   printf("{%s}$",cwd);
   fgets(polecenie, sizeof(polecenie), stdin);
   if(polecenie[strlen(polecenie) - 1] == '\n') polecenie[strlen(polecenie) - 1] = 0;
   if(strcmp(polecenie, "help")==0) printf("informacje o autorze\n");
   else if(strcmp(polecenie, "login")==0){ getlogin_r(login,sizeof(login)); printf("%s\n",login);}
   else if(strcmp(polecenie,"exit")==0) return 0;
   else printf("Bledne polecenie.\nDostepne opcje programu- wpisz help\n");
   }
return 0;
}

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Z tym loginem, to nie wiem czy nie chodziło, żeby wyświetlał się ze znakiem zachęty.

 

Z cd i innymi poleceniami z argumentami można różnie podejść:

-na chama dajesz w warunku czy pierwsze litery napisu pasują (przy dłuższych trochę uciążliwe w pisaniu)

-korzystasz z funkcji wyszukujących na stringach (np. strstr) czy dane polecenie znajduje się w pobranym napisie i czy znajduje się na początku

-dzielisz napis na kawałki (np. strtok) i sprawdzasz po kolei co i jak

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Ogarnęłam login przy znaku zachety, ale poza cd nie wiem jakie inne polecenia moze ta powłoka wykonywać :mad:

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

A jakie chcesz żeby wykonała? :Up_to_s:

Nie chciałbym niczego narzucać, pomyśl przez chwilę jakie polecenia w takiej powłoce by się przydały. Jak już masz zmianę katalogu czy zaraz będziesz miał, to kolejne polecenie wręcz samo się nasuwa.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Jeśli jest(a właściwie może będzie, postaram się podołać) zmiana katalogu... To jakieś kopiowanie/przenoszenie pliku do innego katalogu?

 

EDIT: Nie wiem, siedze pare godzin i załamuję ręce. Termin oddania projektu sie zbliza a ja mam prawie nic.

 

Próbowałam coś dodać, szukałam w internecie, to co dodalam wyroznilam odstępami. POMOCY NIE DZIAŁA

 

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#define BUFFER_SIZE 1024

int strcmp(const char *s1, const char *s2);
int chdir(const char *path);
int getlogin_r(char *buf, size_t bufsize);
char* strstr (const char* str1, const char* str2);
char *strcat (char* strTo, const char* strFrom);

void  p(char *polecenie, char **argv);

int main()
{
printf("\n\n     Witaj w moim programie microshell! Jesli potrzebujesz pomocy-wpisz help  \n\n\n");

char polecenie[100];
char cwd[100];
char login[100];
char  *gdir;
char  *dir;
char  *to;
char buf[100];
char *argv[bUFFER_SIZE];

while(1)
   {
   getcwd(cwd,sizeof(cwd));
   getlogin_r(login,sizeof(login));
   printf("{%s}%s$ ",cwd,login);
   fgets(polecenie, sizeof(polecenie), stdin);
   if(polecenie[strlen(polecenie) - 1] == '\n') polecenie[strlen(polecenie) - 1] = 0;


   p(polecenie, argv);


   if(strcmp(polecenie, "help")==0) printf("exit- wyjscie z programu\n");

   if(strstr(argv[0], "cd")!=NULL)
   {
       gdir = getcwd(buf, sizeof(buf));
       dir = strcat(gdir, "/");
       to = strcat(dir, argv[1]);

       chdir(to);
       continue;
   }


   else if(strcmp(polecenie,"exit")==0) exit(0);
   else printf("Bledne polecenie.\nDostepne opcje programu- wpisz help\n");
   }
}

 

EDIT2: Kolega mi podpowiedział żeby rozbić polecenie na pojedyncze wyrazy z uzyciem warunku while(line!=10), ktory oznacza end of line w kodzie ascii, ale nie do konca wiem jak to podzielić...

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Takie pytanka:

-po co deklarujesz funkcje, które są definiowane w dołączonych nagłówkach?

-gdzie jest implementacja funkcji p, co ta funkcja ma robić?

 

Odnośnie poleceń, to myślałem nad wyświetleniem zawartości katalogu.

Kopiowanie pliku nie jest trudne ale musisz z polecenia wyciągnąć 2 argumenty. Chyba łatwiej zrobić wyświetlenie zawartości pliku.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

  • Ostatnio przeglądający   0 użytkowników

    Brak zarejestrowanych użytkowników przeglądających tę stronę.

  • Tematy

  • Odpowiedzi

    • Świetne rady, autor tematu gra w 3440x1440, więc jakim cudem warto zmieniać 4070Ti na 4070Ti Super, skoro premiera RTX 5000 jest tak nieodległa ? Zanim braknie mu 12GB VRAM w tej rozdzielczości to będzie premiera RTX 6000. Więc @andriejek69 jak masz zmieniać teraz kartę to albo coś dużo mocniejszego, albo czekaj na nowe RTXy. Chyba, że faktycznie chcesz pograć w Cyberpanka z Path Tracingiem, ale tam nawet 4070Ti Super z 16GB to będzie za mało. Zrobisz ja uważasz, ale osobiście uważam taką zmanię za kompletnie bezsensowną, bo obecna kara Ci wystarczy do tej rozdzielczości, a jak zmieniać to na 4090, żeby faktycznie poczuć różnicę, teraz dostaniesz 10% to wydajności. Jedyna opcja to sprzedaż obecnej karty za dobrą cenę i niewielka dopłata.
    • Trudne się wylosowało... Monitorów z tunerem jest jak na lekartwo a szybszych niz 60hz tym bardziej. Nie ma mowy też o oledzie ani miniledzie z tunerem chyba że chodzi o telewizor to już prędzej coś znajdziesz.  Nie podałeś specyfikacji swojego komputera to też niezbyt można powiedzieć czy poradzi sobie z monitorem 4k np. (Samsung monitor m7 i m8) mają smart tv ale tunera już nie mają... Dodatkowo są na matrycy VA co nie każdemu może przypaść do gustu. Najlepszym rozwiązaniem będzie kupno możliwie najlepszego monitora na miniledzie/oled (jeżeli nadal mówimy o budżecie 4000zł) i jakiegoś smartboxa (googletv) z tunerem i podłączenie go do monitora poprzez HDMI.
    • Witam Proszę o ocenę zestawu do grania w 1440p i ewentualne propozycje zmian, chciałabym żeby wszystko zamknęło się w 7tys. Preferuję połączenie Intel/Nvidia, najlepiej jak najmniej RGB, dyski już posiadam (2 SSD Sata). Procesor i5 14600KF Karta Gigabyte GeForce RTX 4070 Super Windforce OC 12GB Płyta główna MSI B760 Gaming Plus WIFI lub MSI MAG B760 Tomahawk WIFI (wcześniej rozważałam również Gigabyte B760 Gaming X AX) Zasilacz Seasonic Focus GX - 750W Lexar Ares RGB 32GB 6400MHz CL32 Obudowa Genesis Irid 505F Z chłodzeniem mam problem, ponieważ chciałam zakupić Deepcool'a AK620, jednak nie jest dostępny w sklepie komputronika (sklep wybrałam ze względu możliwości odbioru komputera w moim mieście). Niestety ten ma dość ograniczony wybór chłodzeń. Tak samo jak widać mocno zastanawiam się nad płytą główną, jestem otwarta na propozycje.
    • https://www.rtings.com/monitor/learn/research/vrr-flicker  
    • Ja czego nie rozumiem? No ja rozumiem jaka jest różnica pomiędzy odbiornikiem prądu a generatorem. Z tego co widzę hybrydy się zgłasza. Czy Ci się to podoba czy nie. To nie jest offgrid.  Tak samo jak magazyn energii. Mimo iż ludzie używają je wewnątrz domu, to muszą być zgłaszane.  To że chińczyk mówi, że falownik nie wysyła nadmiaru energii poza sieć nie ma żadnego znaczenia jeśli podepniesz to do sieci.  Czy na rondo nie ma liczników? Na enmasz umowy tam z energetyka? Nie da się zamontować normalnej instalacji? Co powiedział Ci dostawca prądu? Jeśli sąsiada z działki wywali choćby radio na drugi tydzień po montażu Twojego lewego PV, to spodziewaj się problemów.  Jak udowodnił aż że Twój chiński szajs jest przekozak wówczas? Będziesz miał na to jakieś papiery?  Ze specyfiki pracy jaką oczekujesz. Ta sama zasada działania Cię interesuje. Będziesz szukał paneli gruntowych? A czym różnią się takie od paneli dachowych albo balkonowych? Zestaw balkonowy to jest to co szukać powinieneś. Bo zestawów RODo nie robi a raczej?  Zacznijmy od tego, że zacząłeś od złej strony, bo zamiast falownika i budowania hybrydy, podpina się takie rzeczy prosto w panele. Pompa na prąd stały o szerokim napięciu działania pyrka sobie jak ma napięcie i tyle. 
  • Aktywni użytkownicy

×
×
  • Dodaj nową pozycję...